Tkinter-访问复选框的类值

时间:2018-08-08 16:26:08

标签: python tkinter

我正在尝试一个可行的示例,当在tkinter GUI中单击按钮时,检索gui中的文本。我正在使用Python 36。

如何从按钮内访问guiCheckState变量?

from tkinter import *
from tkinter import ttk
import tkinter as tk

class MyGUI():
    def __init__(self, master):
        self.master = master

        self.printButton = Button(master, text="PRINT VALUE", width=17, command=Main.printButton, background='GREEN').grid(row=1,column=0,sticky="w")

        guiCheckState = IntVar(master)
        self.testCheck = Checkbutton(master, text="Max Price: ", variable=guiCheckState, background='#b3d0e8').grid(row=13,column=0,sticky="w")

class Main():
    def main():
        root = Tk() 
        root.geometry('300x300')
        root.configure(background='#b3d0e8')
        root.protocol("WM_DELETE_WINDOW", exit)
        gui = MyGUI(root)
        root.mainloop()

    def printButton():
        print(MyGUI.guiCheckState) #AttributeError: type object 'MyGUI' has no attribute 'guiCheckState'

Main.main()

谢谢!

2 个答案:

答案 0 :(得分:2)

如果要访问guiCheckState,则必须做几件事。首先,它必须是一个实例变量。如所写,它只是一个局部变量。在python中,要将变量设为实例变量,您需要在变量前加上self.

self.guiCheckState = IntVar(master)

这样,如果您引用了MyGUI的实例,则可以通过该实例来引用变量:

gui = MyGUI()
gui.guiCheckState

但是,guiCheckState是一个对象,因此,如果需要该对象的值,则需要调用其get方法:

print(gui.guiCheckState.get())

在您的示例中,您错误地调用了main(),并且您将该函数中的gui设置为局部变量。同样,为了能够在定义它的函数之外引用它,您需要将其设置为实例变量:

self.gui = MyGUI(root)

为此,main必须是一个实例方法。在python中,这意味着它必须接受self作为它的第一个参数(实际上,必须命名为self,但这是一个约定,没有python程序违反)。 printButton函数也是如此。

最后,您在按钮中错误地引用了printButton。您需要Main而不是类Main的实例(例如:the_main_instance.printButton而不是Main.printButton)。您可以通过添加一些语法糖在python中拥有类函数,但是在您的示例中,最好将它们保留为实例函数。

该解决方案有些棘手,因为MyGUI的实例没有引用Main的实例。因此,如果您希望MyGUI的实例能够引用它,我们必须将其传递给MyGUI

最后一点建议:在python中,当您执行foo().bar()时,结果为bar()的值。因此,当您执行类似Button(...).grid(...)的操作时,结果就是grid(...)的结果。在tkinter中,.grid(...)返回None。最佳做法是始终在单独的行上调用grid(或packplace),以免变量被设置为None。另外,经验告诉我,将布局语句组合在一起可以使代码更易于理解。

好,再更多条建议。 PEP8(Python样式指南)出于某些很好的理由而阻止通配符的导入。不幸的是,许多tkinter教程都使用通配符导入。许多人认为这是不好的做法。由于您刚刚起步,所以我建议您坚持使用PEP8。

将所有内容包装在一起,您的代码将如下所示:

import tkinter as tk

class MyGUI():
    def __init__(self, master, main):
        self.master = master
        self.main = main

        self.printButton = tk.Button(master, text="PRINT VALUE", width=17,
                                     command=self.main.printButton,
                                     background='GREEN')

        self.guiCheckState = tk.IntVar(master)
        self.testCheck = tk.Checkbutton(master, text="Max Price: ",
                                        variable=self.guiCheckState,
                                        background='#b3d0e8')

        self.printButton.grid(row=1,column=0,sticky="w")
        self.testCheck.grid(row=13,column=0,sticky="w")

class Main():
    def main(self):
        root = tk.Tk() 
        root.geometry('300x300')
        root.configure(background='#b3d0e8')
        root.protocol("WM_DELETE_WINDOW", exit)
        self.gui = MyGUI(root, self)
        root.mainloop()

    def printButton(self):
        print(self.gui.guiCheckState.get())

main = Main()
main.main()

答案 1 :(得分:1)

与TKinter无关,但看起来应该是self.guiCheckStateself.gui,而您应该使用self.gui.guiCheckState来引用它。

guiCheckState应该是MyGui的 instance 的字段,而gui应该是Main的字段。