我正在编写一个小型的Tkinter / Python程序,它有一个可变长度的复选框列表(在运行时确定)。
我希望能够随时阅读所有复选框的状态,但我不确定应该怎么做。
以下是用于生成列表的代码段(从this post采用):
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;
问题是我的处理程序被调用一次(当创建Checkbuttons时),而我希望每次点击Checkbutton
(选中或取消选中)时调用它,并且当它被调用时,我希望它更新lst。
答案 0 :(得分:3)
你的CheckButton命令正在执行回调,因为这就是你告诉它要做的事情。该命令应该是对单击检查按钮时tkinter可以执行的函数的引用。 Tkinter将事件对象传递给回调函数。请参阅此Effbot教程,但看起来您正在尝试实现其模式。您可以按照here的说明从event.widget属性获取对checkbutton的引用。最后,如果要在回调中引用变量,则需要将变量附加到“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))
答案 1 :(得分:0)
我认为您所要求的内容可以来自here。
对于每个item in lst
,必须先为其创建不同的IntVar()
变量,以指示每个复选框的独立状态。
除了手动创建它们之外我没有看到其他方式(我假设你没有数百个复选框)。
我将重新使用this回答中的代码并执行以下操作:
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))
答案 2 :(得分:0)
我有同样的问题。试试这个:
cb = tk.Checkbutton(text="/dev/%s" % item, variable=v, command=lambda: self.cb(index))
如果将方法作为lambda函数传递,它会对变量的每次更改执行方法。
答案 3 :(得分:0)
我个人不会使用tk.IntVar()/ tk.StringVar()等,但也许我应该这样做。 这可能不是最好的方法,但我认为这很容易理解。不要批评并告诉我什么是非常糟糕而不是pythonic所以我可以提高自己(我还是一个新手)。
我创建一个交互器,然后我在循环中创建我的检查按钮,在回调中,我在参数中传递了checkbutton和迭代器的值。
...
self.listeColonneFile1 = []
self.chbFile1 = []
indice = 0
for column in dfFile1.columns:
btn = ttk.Checkbutton(self.frameCheckButtonsFile1,
text=column,
command=lambda i=indice, col=column: self.callback_onCheck(col, i)
)
self.chbFile1.append(btn)
self.chbFile1[indice].grid(row = indice, column = 0, sticky="nw")
self.chbFile1[indice].state(['!alternate'])
indice += 1
在我的回调中,我有一个检查的所有checkButton的列表(好吧,不是ChB,但是它的文本或它的值):
def callback_onCheck(self, column, indice):
if self.chbFile1[indice].instate(['selected']) == True:
self.listeColonneFile1.append(column)
else:
self.listeColonneFile1.remove(column)
PS:dfFile1是一个pandas DataFrame,请参阅the doc