2017-10-20 74 views
1

我有一个使用Tk的Python小GUI应用程序。它有几个过滤器---一个文本条目(它们设置过滤器值)和复选框(设置过滤器开启/关闭)。我创建过滤器从ttkLabelframe inhetrited类:tkinter中的依赖小部件

from tkinter.ttk import Labelframe 
import tkinter as tk 

class FilterWidget(Labelframe): 

    def __init__(self, parent, label): 
     Labelframe.__init__(self, parent, text=label) 
     self.grid() 
     self._entry = tk.Entry(self) 
     self._entry.grid(row=0, column=0) 
     self._checkbox = tk.Checkbutton(self, command=lambda: print(self)) 
     self._checkbox.grid(row=0, column=1) 

然后,我创建这个类的几个实例,并放置在GUI:

root = tk.Tk() 

source_filter = FilterWidget(root, "Source") 
source_filter.grid(row=0, column=0) 
level_filter = FilterWidget(root, "Severity") 
level_filter.grid(row=0, column=1) 

root.mainloop() 

窗口小部件被创建并正确显示。但是,当其中一个复选框被点击并改变状态时,另一个改变状态!

当点击不同的复选框时,print命令输出.!filterwidget.!filterwidget2,所以这些是单独的对象。看起来他们在某种程度上隐含地同步,但我不知道这是怎么发生的。

所以,问题是:如何消除这种依赖并使复选框相互独立?

+0

我没有得到你描述的行为。你确定这个确切的代码有问题吗? –

+0

是的,答案中的两个片段是完整的代码,它为我重现了问题。我在Windows 7上运行Python 3.6.2(v3.6.2:5fd33b5,Jul 8 2017,04:14:34)[MSC v.1900 32 bit(Intel)])。 – Month

回答

2

由于the docs提到,

要使用Checkbutton,你必须创建一个Tkinter的变量。要检查 按钮的状态,查询变量。

下面是您的代码更新为使用IntVar来存储Checkbutton状态。

from tkinter.ttk import Labelframe 
import tkinter as tk 

class FilterWidget(Labelframe): 
    def __init__(self, parent, label): 
     Labelframe.__init__(self, parent, text=label) 
     self._entry = tk.Entry(self) 
     self._entry.grid(row=0, column=0) 

     self._var = tk.IntVar() 
     callback = lambda: print(self._entry.get(), self._var.get()) 
     checkbox = tk.Checkbutton(self, variable=self._var, command=callback) 
     checkbox.grid(row=0, column=1) 

root = tk.Tk() 

source_filter = FilterWidget(root, "Source") 
source_filter.grid(row=0, column=0) 
level_filter = FilterWidget(root, "Severity") 
level_filter.grid(row=0, column=1) 

root.mainloop() 
+0

是的,解决了这个问题。我从来没有明确地使用复选框的值,只依赖回调,所以我认为创建一个没有必要。由于没有对文档给予足够的重视,我更加愚弄。 – Month

+0

@Month永远不要低估Tkinter以各种怪癖困扰你的能力。 ;) –