我正在尝试一个可行的示例,当在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()
谢谢!
答案 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
(或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()
答案 1 :(得分:1)
与TKinter无关,但看起来应该是self.guiCheckState
和self.gui
,而您应该使用self.gui.guiCheckState
来引用它。
即guiCheckState
应该是MyGui的 instance 的字段,而gui
应该是Main
的字段。