如何获取Tkinter中多个复选按钮的状态?
我正在写一个小的Tkinter/Python程序,这个程序有一个长度可变的复选框列表(这个长度是在运行时决定的)。
我希望能够随时读取所有复选框的状态,但我不太确定该怎么做。
下面是生成这个复选框列表的代码片段(改编自这篇帖子):
def relist(self):
self.text.delete(1.0,END)
p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE)
lst = p.communicate()[0].split('\n')
print lst
for item in lst:
v = tk.IntVar()
cb = tk.Checkbutton(text="/dev/%s" % item, variable=v, command=self.cb(index))
self.text.window_create("end", window=cb)
self.text.insert("end", "\n") # to force one checkbox per line
还有我的一个简单的处理函数:
def cb(self,idx):
print ("var is %s", str(idx))
lst[idx] = 1;
问题是我的处理函数只在创建复选框的时候被调用了一次,而我希望每次点击复选框(无论是选中还是取消选中)时都能调用这个函数,并且在调用时更新列表lst。
4 个回答
0
我也遇到过同样的问题。试试这个:
cb = tk.Checkbutton(text="/dev/%s" % item, variable=v, command=lambda: self.cb(index))
如果你把方法作为一个lambda函数传递,那么每当变量发生变化时,这个方法就会被执行。
0
我觉得你问的问题可以从这里找到答案。
对于每一个item in lst
,你需要事先创建不同的IntVar()
变量,这样才能表示每个复选框的独立状态。我想不出其他办法,只能手动创建这些变量(我假设你不会有上百个复选框)。我会重用这个答案中的代码,接下来会这样做:
def relist(self):
self.text.delete(1.0,END)
p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE)
lst = p.communicate()[0].split('\n')
print lst
self.var1 = tk.IntVar()
self.var2 = tk.IntVar()
self.var3 = tk.IntVar()
.
.
.
vars = [self.var1,self.var2,self.var3,...]
for item, var in zip(self.lst, vars):
cb = tk.Checkbutton(text="/dev/%s" % item, variable=var, command= lambda: self.myCallback(var))
self.text.window_create("end", window=cb)
self.text.insert("end", "\n") # to force one checkbox per line
def myCallback(self,event,var):
each_var = var.get()
print ("var is %s", str(each_var))
3
你的CheckButton命令正在执行回调函数,因为你就是这么设置的。这个命令应该指向一个函数,当你点击复选框时,tkinter就会执行这个函数。tkinter会把事件对象传递给回调函数。你可以查看这个Effbot的教程,不过看起来你已经在尝试实现他们的模式了。你可以通过事件的widget属性来获取复选框的引用,具体解释可以在这里找到。最后,如果你想在回调函数中使用你的变量,需要把它和“self”关联起来。
def relist(self):
self.text.delete(1.0,END)
p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE)
lst = p.communicate()[0].split('\n')
print lst
self.var = tk.IntVar()
for item in lst:
cb = tk.Checkbutton(text="/dev/%s" % item, variable=self.var, command=self.myCallback)
self.text.window_create("end", window=cb)
self.text.insert("end", "\n") # to force one checkbox per line
def myCallback(self,event):
var = self.var.get()
print ("var is %s", str(var))