14

I have a list of variable length and want to create a checkbox (with python TKinter) for each entry in the list (each entry corresponds to a machine which should be turned on or off with the checkbox -> change the value in the dictionary).

print enable
{'ID1050': 0, 'ID1106': 0, 'ID1104': 0, 'ID1102': 0}

(example, can be any length)

now the relevant code:

for machine in enable:
    l = Checkbutton(self.root, text=machine, variable=enable[machine])
    l.pack()
self.root.mainloop()

This code produces 4 checkboxes but they are all either ticked or unticked together and the values in the enable dict don't change. How to solve? (I think the l doesn't work, but how to make this one variable?)

Sebastian
  • 5,471
  • 5
  • 35
  • 53

3 Answers3

20

The "variable" passed to each checkbutton must be an instance of Tkinter Variable - as it is, it is just the value "0" that is passed, and this causes the missbehavior.

You can create the Tkinter.Variable instances on he same for loop you create the checkbuttons - just change your code to:

for machine in enable:
    enable[machine] = Variable()
    l = Checkbutton(self.root, text=machine, variable=enable[machine])
    l.pack()

self.root.mainloop()

You can then check the state of each checkbox using its get method as in enable["ID1050"].get()

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • 1
    Thank you! The checkboxes works now, just one question: how can I read the variables outside of the tkinter class (I have it set up as in: http://stackoverflow.com/a/1835036/1102225). I tried everything. When I use `print enable[machine].get() AttributeError: 'int' object has no attribute 'get'` So I tried: `print app.enable[machine].get() AttributeError: 'MyTkApp' object has no attribute 'enable'` (app is the object of the tkinter class called MyTkApp) And when I do it without the get: `print enable[machine] PY_VAR0` – Sebastian Dec 19 '11 at 10:57
  • 1
    Oh I got it myself! I included a function in the tkinter class to return the value: `def read(self, machine): return enable[machine].get() ` then outside of the class you can for example just call: `print app.read(1050)` – Sebastian Dec 19 '11 at 12:29
1

Just thought I'd share my example for a list instead of a dictionary:

from Tkinter import *

root = Tk()    

users = [['Anne', 'password1', ['friend1', 'friend2', 'friend3']], ['Bea', 'password2', ['friend1', 'friend2', 'friend3']], ['Chris', 'password1', ['friend1', 'friend2', 'friend3']]]

for x in range(len(users)):
    l = Checkbutton(root, text=users[x][0], variable=users[x])
    print "l = Checkbutton(root, text=" + str(users[x][0]) + ", variable=" + str(users[x])
    l.pack(anchor = 'w')

root.mainloop()

Hope it helps

kidchrono
  • 11
  • 3
0

You can use this code. The exec() command allows you to execute a string variable.

from tkinter import *

root = Tk()    

users = ['Anne', 'Bea', 'Chris']

variables=[]

for x in range(len(users)):


    var_ejecutar=f"global {users[x]}_double_var"
    exec(var_ejecutar)

    var_ejecutar=f"{users[x]}_double_var=DoubleVar()"
    exec(var_ejecutar)

    variables.append(f"{users[x]}_double_var")

    var_ejecutar=f"""l = Checkbutton(root, text=\"{str(users[x][0])}\", 
        variable={users[x]}_double_var,onvalue = 1,offvalue = 0)"""
    exec(var_ejecutar)
    
    var_ejecutar="l.pack(anchor = 'w')"
    exec(var_ejecutar)


def get_val():

    for i in variables:

        var_ejecutar=f"print({i}.get())"

        exec(var_ejecutar)

btn= Button(root, text="ACTUALIZAR", state=NORMAL, command=get_val,bg="#C2CDD1") #crear boton
btn.pack(anchor = 'w')

root.mainloop()