TKInter复选框变量始终为0

时间:2015-04-13 23:18:13

标签: python tkinter

我正在使用Python的TkInter模块进行GUI。下面是一个简单的复选框代码。

def getCheckVal():
    print cbVar.get()

windowTime=Tk.Tk()
cbVar = Tk.IntVar()
btnC = Tk.Checkbutton(windowTime, text="Save", variable = cbVar, command=getCheckVal)
btnC.grid()
windowTime.mainloop()

此代码工作正常。每次勾选复选框,我都会得到1,否则为0。

但是,当我在从另一个TkInter命令调用的函数中运行相同的代码时(按下按钮时),它会停止工作。我总是得到0作为值。

class GUIMainClass:

    def __init__(self):
        '''Create the main window'''
        self.window = Tk.Tk()

    def askUser(self):
        def getCheckVal():
            print cbVar.get()

        windowTime=Tk.Tk()
        cbVar = Tk.IntVar()
        btnC = Tk.Checkbutton(windowTime, text="Save", variable = cbVar,
                              command=getCheckVal)
        btnC.grid()
        windowTime.mainloop()

    def cmdWindow(self):
        frameShow=Tk.Frame(self.window)
        frameShow.grid()
        btnSwitch = Tk.Button(frameShow, text='Show Plots', command=self.askUser)
        btnSwitch.grid()
        self.window.mainloop()

GUIObj=GUIMainClass()
GUIObj.cmdWindow()

这很不寻常。可能出现什么问题?

编辑:我使用了2个主循环因为我想在单击“显示绘图”按钮时打开一个单独的窗口(windowTime)。这个新窗口应该有复选框。

2 个答案:

答案 0 :(得分:2)

您的windowTimecbVar等变量在函数的本地范围内定义。当askUser()完成执行时,这些值将被丢弃。在它们前面添加self.以将它们保存为实例变量。

程序中应该只有一个mainloop()来运行主Tkinter根对象。尝试将它作为程序的最后一行。我建议您在Effbot上阅读有关如何设置Tkinter应用程序的信息。

答案 1 :(得分:2)

我不确定您要做的是什么,但有一个问题是您在TK.IntVar方法中创建的cbVar调用askUser()将会当函数返回时被删除,所以你需要将它附加到在那之后仍然存在的东西。虽然你可以把它变成一个全局变量,但更好的选择是使它成为更持久的东西的属性,并且具有更长的寿命"。

另一个可能的问题是,通常在单个mainloop()应用程序中只应调用一次Tkinter。您想要做的就是显示通常所知的对话窗口,Tkinter也支持。内置了一些标准内容,还有一些更通用的类来简化创建自定义类。以下是我发现的一些documentation,其中详细介绍了它们。您可能还会发现查看源代码很有帮助。 在Python 2中,它位于/Lib/lib-tk/tkSimpleDialog.py文件中 在Python 3中,代码位于名为/Lib/tkinter/simpledialog.py的文件中。

下面是采用后一种方法的代码,并从包含Tkinter库的通用库中派生名为GUIButtonDialog的自定义对话框类,该库名为Dialog

try:
    import Tkinter as Tk    # Python 2
    from tkSimpleDialog import Dialog
except ModuleNotFoundError:
    import tkinter as Tk    # Python 3
    from tkinter.simpledialog import Dialog


class GUIButtonDialog(Dialog):
    """Custom one Button dialog box."""
    def __init__(self, btnText, parent=None, title=None):
        self.btnText = btnText
        Dialog.__init__(self, parent, title)

    def getCheckVal(self):
        print(self.cbVar.get())

    def body(self, master):
        """Create dialog body."""
        self.cbVar = Tk.IntVar()
        self.btnC = Tk.Checkbutton(master, text=self.btnText, variable=self.cbVar,
                                   command=self.getCheckVal)
        self.btnC.grid()

        return self.btnC  # Return the widget to get inital focus.

    def buttonbox(self):
        # Overridden to suppress default "OK" and "Cancel" buttons.
        pass


class GUIMainClass:

    def __init__(self):
        """Create the main window."""
        self.window = Tk.Tk()

    def askUser(self):
        """Display custom dialog window (until user closes it)."""
        GUIButtonDialog("Save", parent=self.window)

    def cmdWindow(self):
        frameShow = Tk.Frame(self.window)
        frameShow.grid()
        btnSwitch = Tk.Button(frameShow, text='Show Plots', command=self.askUser)
        btnSwitch.grid()
        self.window.mainloop()


GUIObj = GUIMainClass()
GUIObj.cmdWindow()