【问题标题】:TKInter checkbox variable is always 0TKInter 复选框变量始终为 0
【发布时间】:2018-09-27 02:23:46
【问题描述】:

我将 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)。这个新窗口应该有复选框。

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

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

    您的程序中应该只有一个mainloop() 来运行主要的Tkinter 根对象。试着把它放在程序的最后一行。我建议阅读Effbot 以了解如何设置Tkinter 应用程序。

    【讨论】:

    • 另外,我将self 添加到所有内容中。没用。
    • tkinter 应用程序中应该仍然只有一个 mainloop()。您不需要每个窗口一个。请参阅我的建议以了解设置 tkinter 应用程序的正确方法。
    【解决方案2】:

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

    另一个可能的问题是,通常在单个Tkinter 应用程序中应该只调用一次mainloop()。看来您想要做的是显示通常称为 Dialog Window 的内容,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()
    

    【讨论】:

    • 复选框应在新窗口中打开。在这里,它在同一个窗口中。
    • sbhatla:好的,请参阅我的更新答案。迟到总比没有好,不是吗? ;¬)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    相关资源
    最近更新 更多