Tkinter用复选框禁用多个输入框
在Python 2.7中,我想通过一个复选框来控制一个“输入框”的状态,让它变成正常或禁用。
通过参考这个问题 用复选框禁用控件?,我可以用一个复选框和一个输入框来实现这个功能。
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import Tkinter as tk
root = tk.Tk()
class Principal(tk.Tk):
def __init__(self, *args, **kwargs):
self.foo = tk.StringVar()
self.nac = tk.IntVar()
self.ck1 = tk.Checkbutton(root, text='test',
variable=self.nac, command=self.naccheck)
self.ck1.pack()
self.ent1 = tk.Entry(root, width=20, background='white',
textvariable=self.foo, state='disabled')
self.ent1.pack()
def naccheck(self):
print "check"
if self.nac.get() == 0:
self.ent1.configure(state='disabled')
else:
self.ent1.configure(state='normal')
app = Principal()
root.mainloop()
但是,当我想要有两个或更多的复选框和输入框配对时,就出现了问题。因为在我的最终界面中,可能会有20对或者更多这样的配对,所以我希望能避免写20个相同的“naccheck”方法。
我尝试了这个:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import Tkinter as tk
root = tk.Tk()
class Principal(tk.Tk):
def __init__(self, *args, **kwargs):
self.foo = tk.StringVar()
self.nac = {}
self.ent = {}
self.ent["test"] = tk.Entry(root, width=20, background='white', textvariable=self.foo, state='disabled')
self.ent["test"].pack()
self.ent["image"] = tk.Entry(root, width=20, background='white', textvariable=self.foo, state='disabled')
self.ent["image"].pack()
self.nac["test"] = tk.IntVar()
self.ck1 = tk.Checkbutton(root, text='test', variable=self.nac["test"], command=self.naccheck("test"))
self.ck1.pack()
self.nac["image"] = tk.IntVar()
self.ck1 = tk.Checkbutton(root, text='image', variable=self.nac["image"], command=self.naccheck("image"))
self.ck1.pack()
def naccheck(self,item):
print "check "+item
print self.nac[item].get()
if self.nac[item].get() == 0:
self.ent[item].configure(state='disabled')
else:
self.ent[item].configure(state='normal')
app = Principal()
root.mainloop()
不幸的是,当我运行这段代码时,每个复选框的“naccheck”方法会立即被调用,而不是在我点击某个复选框后才调用……
我哪里做错了呢?
1 个回答
8
解决这个问题的方法有很多种。一个方法是把输入框和复选框的变量传递到你的检查函数里。首先创建输入框和变量。然后,创建复选框,并把变量和输入框传给你的回调函数:
ent = tk.Entry(...)
var = tk.IntVar()
chk = tk.Checkbutton(..., command=lambda e=ent, v=var: self.naccheck(e,v))
注意这里使用了lambda,这是一个简单的技巧,用来创建匿名函数。这样你就可以在不需要创建命名函数的情况下,把参数传给回调函数。另一个选择是使用 functools.partial。在StackOverflow上肯定有很多关于这个的例子,因为这是一个非常常见的问题。
接下来,你需要修改你的函数,以便接受参数:
def naccheck(self, entry, var):
if var.get() == 0:
entry.configure(state='disabled')
else:
entry.configure(state='normal')