0

I am trying to get a button to be disabled when the entrybox is empty and enabled when I type in something.

this is a part where the button and the entybox is.

self.description = tk.StringVar()
self.entry_ds = ttk.Entry(self, width=25, 
                          textvariable=self.description)
self.entry_ds.grid(column=0, row=1, padx=13, pady=4)
self.entry_ds.focus()

self.co_button = ttk.Button(self, text='Confirm', command=self.on_press_ds)
self.co_button.grid(column=0, row=2, pady=4)

def on_press_ds(self):
    description = self.description.get()
    if description:
        self.master.listbox.insert('end', description)
    self.destroy_ds()
    self.destroy()

I've tried using

if not self.description.get():
    self.co_button['state'] = 'disabled'

and was able to get the entrybox disabled when it's empty, but I was unable to get enabled when I typed in something.

Moses Kim
  • 242
  • 3
  • 16

1 Answers1

1

The simplest way would be to add a trace on the related variable. Within the trace you can change the state of the button based on the current value.

First, define a function to be called by the trace:

def on_entry_trace(self, *args):
    new_state = "disabled" if self.description.get() == "" else "normal"
    self.co_button.configure(state=new_state)

Next, create the trace and force it to be called to set the initial state. You would do this in the same function that creates the variable.

The first argument to trace tells tkinter when to call the associated function. "w" says to call the function whenever the variable is written to (ie: the value changes). The second argument is the function to be called.

self.description.trace("w", self.on_entry_trace)
self.description.set("")  # initialize the state

Once that is set up, the function will be called whenever the value of the entry widget changes.

For more information on what the arguments to a function called by trace see What are the arguments to Tkinter variable trace method callbacks?

Effbot has a decent write-up of the variable traces, including information about traces, on the page The Variable Classes (BooleanVar, DoubleVar, IntVar, StringVar)

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I added your code. But for function ```on_entry_trace``` pycharm says parameter```*args``` is not used. And gives me errors like ```Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\82104\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__ return self.func(*args) File "C:\Users\82104\PycharmProjects\Macro\GUI.py", line 256, in on_entry_trace self.co_button.configure(state=new_state) AttributeError: 'Description' object has no attribute 'co_button'``` – Moses Kim May 08 '19 at 07:09
  • ```co_button``` is in class ```Description``` I don't understand why it's not attributed. – Moses Kim May 08 '19 at 07:11
  • @김상언: I can't help you with that -- it's all code that you didn't show in your question. As for pycharm, it's telling the truth: `*args` is not used. However, the arguments are required because the trace will send parameters to the function. – Bryan Oakley May 08 '19 at 12:59