Home > other >  Tkinter: How can I check if any of the widgets of a specific frame have changed?
Tkinter: How can I check if any of the widgets of a specific frame have changed?

Time:01-08

What is the best way to check if any widget (or variable linked to it) of a given frame(frm1) has changed and take an action. For example activate a button.

I would like that when something was typed in the entries or changed the combobox or checkbox, the 'changed_content' function would be executed

from tkinter import *
from tkinter import ttk
from tkinter.messagebox import showinfo

class Defaultframe(Tk):
    def __init__(self):
        Tk.__init__(self)

        self.geometry('500x300')
        self.title('Tkinter')

        self.text1 = StringVar()
        self.text2 = StringVar()
        self.text3 = StringVar()
        self.var1 = IntVar()
        self.var2 = IntVar()

        self.set_widgets()
        return


    def changed_content(self):
        showinfo('Information', 'The content has been changed')
        self.btn2.configure(state='normal')
        return


    def set_widgets(self):
        #Frame1
        self.frm1 = ttk.Frame(self).pack(side=TOP)

        self.lbl = ttk.Label(self.frm1, text='Text1').pack(pady=5)
        self.ent1 = ttk.Entry(self.frm1, textvariable=self.text1).pack(pady=5)

        self.lbl = ttk.Label(self.frm1, text='Text2').pack(pady=5)
        self.my_ent = ttk.Entry(self.frm1, textvariable=self.text2).pack(pady=5)

        self.cbb = ttk.Combobox(self.frm1, 
                        values=[0, 30, 60, 90, 120, 150, 180],
                        state='readonly',
                        textvariable=self.var2)
        self.cbb.pack(pady=5)
        self.cbb.current(3)

        self.ckb = ttk.Checkbutton(self.frm1, text='Hello', variable=self.var1, onvalue=1, offvalue=0).pack(pady=5)
        #---

        

        #Frame2
        self.frm2 = ttk.Frame(self).pack(side=BOTTOM, fill=X)
        ttk.Separator(self.frm2, orient=HORIZONTAL).pack(side=TOP, expand=1, fill=X)
        self.my_ent3 = ttk.Entry(self.frm2, textvariable=self.text3).pack(side=LEFT, padx=1)
        self.btn1 = ttk.Button(self.frm2, text='Cancel').pack(side=RIGHT, padx=1)
        self.btn2 = ttk.Button(self.frm2, text='Save')
        self.btn2.pack(side=RIGHT, padx=1)
        self.btn2.configure(state=DISABLED)
        #---


if __name__== '__main__':
    app = Defaultframe()
    app.mainloop()

CodePudding user response:

Solving for any widget is tough - you'll have to write code specifically for a canvas or a scrollbar or any other widget that isn't associated with a tkinter variable.

For widgets that are associated with a tkinter variable you can apply a trace that will call a function whenever the value changes.

In your code it might look something like this:

class Defaultframe(Tk):
    def __init__(self):
        ...
        self._watch_variables(self.text1, self.text2, self.text3, self.var1, self.var2)

    def _watch_variables(self, *vars):
        for var in vars:
            var.trace_add("write", self._handle_trace)

    def _handle_trace(self, *args):
        self.changed_content()
  •  Tags:  
  • Related