如何获取Tkinter中多个复选按钮的状态?

5 投票
4 回答
9523 浏览
提问于 2025-04-17 11:11

我正在写一个小的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))

撰写回答