我正在尝试获得一个工作示例,即在 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()
谢谢!!!
如果你想访问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
(或pack
或place
(,以便变量不会设置为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()
与 TKinter 无关,但看起来它应该是self.guiCheckState
和self.gui
的,你应该用self.gui.guiCheckState
来引用它。
即guiCheckState
应该是MyGui实例的字段,gui
应该是Main
的字段。