0

How do you check if the user has selected "Other" from the hopOptions selection, and then enable otherEntry if they did? And then disable it again if they select one of the other options.

    class Interface():
        def __init__(self, window):
            frame = Frame(window)
            frame.pack()

            self.hopLabel = Label(frame, text="Hop:", anchor=E)
            self.hopLabel.grid(row=0, column=0, sticky=EW)

            hops = range(0,6)
            hops.append("Other")

            self.selectedHop = StringVar(frame)
            self.selectedHop.set(hops[0])
            self.hopOptions = OptionMenu(frame, self.selectedHop, *hops)
            self.hopOptions.grid(row=0, column=2, sticky=EW)

            self.otherEntry = Entry(frame, state=DISABLED)
            self.otherEntry.grid(row=0, column=1, sticky=EW)

    root = Tk()

    app = Interface(root)

    root.mainloop()
user1527216
  • 1,143
  • 2
  • 13
  • 18

2 Answers2

2

Bind the option menu to a command and add another method to your class. The command will run the class method with the value as an argument anytime an option is changed in the menu. There you can do validation to update the otherEntry widget. Also I would advise not doing from Tkinter import * as it appears that's what you've done. Generally importing an entire package could have conflicts with your namespace. This should suit your needs:

from Tkinter import *

class Interface():
        def __init__(self, window):
            frame = Frame(window)
            frame.pack()

            self.hopLabel = Label(frame, text="Hop:", anchor=E)
            self.hopLabel.grid(row=0, column=0, sticky=EW)

            hops = range(0,6)
            hops.append("Other")

            self.selectedHop = StringVar(frame)
            self.selectedHop.set(hops[0])
            self.hopOptions = OptionMenu(frame, self.selectedHop, *hops, command=self.optupdate)
            self.hopOptions.grid(row=0, column=2, sticky=EW)

            self.otherEntry = Entry(frame, state=DISABLED)
            self.otherEntry.grid(row=0, column=1, sticky=EW)

        def optupdate(self, value):
            if value == "Other":
                self.otherEntry.config(state=NORMAL)
            else:
                self.otherEntry.config(state=DISABLED)

if __name__ == "__main__":
    root = Tk()
    app = Interface(root)
    root.mainloop()
  • Awesome! This worked well! What would you recommend instead of from Tkinter import * ? – user1527216 Sep 19 '14 at 15:51
  • 2
    Generally you would want to use `import Tkinter` or `import Tkinter as tk` and then use `Tkinter.` or `tk.` in front of all your calls to that specific module. That way you don't have conflicting namespaces. See http://stackoverflow.com/questions/2386714/why-is-import-bad and http://stackoverflow.com/questions/2360724/in-python-what-exactly-does-import-import for more information regarding polluted namespaces. –  Sep 19 '14 at 15:57
2

As an alternative to iChar's command approach, Use selectedHop.trace to register a function that will be called whenever the selected item changes.

from Tkinter import *

class Interface():
    def __init__(self, window):
        frame = Frame(window)
        frame.pack()

        self.hopLabel = Label(frame, text="Hop:", anchor=E)
        self.hopLabel.grid(row=0, column=0, sticky=EW)

        hops = range(0,6)
        hops.append("Other")

        self.selectedHop = StringVar(frame)
        self.selectedHop.set(hops[0])
        self.selectedHop.trace("w", self.selected_hop_changed)
        self.hopOptions = OptionMenu(frame, self.selectedHop, *hops)
        self.hopOptions.grid(row=0, column=2, sticky=EW)

        self.otherEntry = Entry(frame, state=DISABLED)
        self.otherEntry.grid(row=0, column=1, sticky=EW)

    def selected_hop_changed(self, *args):
        value = self.selectedHop.get()
        if value == "Other":
            self.otherEntry.config(state=NORMAL)
        else:
            self.otherEntry.config(state=DISABLED)


root = Tk()

app = Interface(root)

root.mainloop()
Kevin
  • 74,910
  • 12
  • 133
  • 166