Home > Enterprise >  Python Tkinter, can't get value of checkbutton as child
Python Tkinter, can't get value of checkbutton as child

Time:11-07

I created some widgets in loop. And i need to get values of em all. I coded:

from tkinter import *
class App():
    def __init__(self):
        self.ws = Tk()
        self.frame = LabelFrame(self.ws)
        self.frame.grid(row=1,column=1)
        for i in range(16):
            e = Label(self.frame, text=str(i   1)   '.')
            e.grid(row=i 1, column=1)
            e1 = Entry(self.frame, width=8)
            e1.grid(row=i 1, column=2)
            e2 = Entry(self.frame)
            e2.grid(row=i 1, column=3)
            check = Checkbutton(self.frame, variable=BooleanVar(), onvalue=True, offvalue=False)
            check.grid(row=i 1, column=4, sticky=E)
        but = Button(self.ws,text='Get ALL',command=self.getall)
        but.grid(row=17,column=1)
        self.ws.mainloop()
    def getall(self):
        list = []
        self.frame.update()
        print('Child List:',self.frame.winfo_children())
        for wid in self.frame.winfo_children():
            if isinstance(wid,Entry):
                list.append(wid.get())
            elif isinstance(wid,Checkbutton):
                self.frame.getvar(wid['variable'])
        print('List:',list)
if __name__ == '__main__':
    App()

It returns:

return self.tk.getvar(name)
.TclError: can't read "PY_VAR0": no such variable

If i click all checkbuttons, it doesn't error but returns empty strings..Whats wrong here?

CodePudding user response:

TKinter couldn't retrieve the variables of your checkboxes, because you have created these variables on the fly inside __init__() scope, hence these variables are living in __init__() call stack only, and once __init__() finished its work, the garbage collector cleans these variables, so they are not reachable any more since they are not live in your main stack.

So, you need to keep them living in your main program stack. I have edited your code by adding a long-lived dict() for storing these checkboxes variables to be able to access them later.

from tkinter import *


class App():
    def __init__(self):
        self.ws = Tk()
        self.frame = LabelFrame(self.ws)
        self.frame.grid(row=1, column=1)
        self.checkboxesValues = dict()
        for i in range(16):
            self.checkboxesValues[i] = BooleanVar()
            self.checkboxesValues[i].set(False)
            e = Label(self.frame, text=str(i   1)   '.')
            e.grid(row=i 1, column=1)
            e1 = Entry(self.frame, width=8)
            e1.grid(row=i 1, column=2)
            e2 = Entry(self.frame)
            e2.grid(row=i 1, column=3)
            check = Checkbutton(self.frame, variable=self.checkboxesValues[i])
            check.grid(row=i 1, column=4, sticky=E)
        but = Button(self.ws, text='Get ALL', command=self.getall)
        but.grid(row=17, column=1)
        self.ws.mainloop()

    def getall(self):
        list = []
        self.frame.update()
        print('Child List:', self.frame.winfo_children())
        for wid in self.frame.winfo_children():
            if isinstance(wid, Entry):
                list.append(wid.get())
            elif isinstance(wid, Checkbutton):
                list.append(self.frame.getvar(wid['variable']))
        print('List:', list)


if __name__ == '__main__':
    App()

Now, checkboxesValues variable lives in your App's object stack, so your checkboxes variables are existing in your memory as long as your object is not destroyed.

  • Related