Python tkinter-将条目小部件值传递给另一个类
我根据前面的一个问题改编了这段代码,该问题整洁地保留了一个导航框,但根据按下的按钮更改了内容框。登录页面有一个条目小部件。我想将它的值(“Paul”say)转移到Play游戏框架中,例如,它会说“这是Paul的游戏页面”。在这种特殊的设置下,如果有人能帮忙,我不知道如何实现它Python tkinter-将条目小部件值传递给另一个类,python,tkinter,Python,Tkinter,我根据前面的一个问题改编了这段代码,该问题整洁地保留了一个导航框,但根据按下的按钮更改了内容框。登录页面有一个条目小部件。我想将它的值(“Paul”say)转移到Play游戏框架中,例如,它会说“这是Paul的游戏页面”。在这种特殊的设置下,如果有人能帮忙,我不知道如何实现它 import tkinter as tk class Page(tk.Frame): def __init__(self, *args, **kwargs): tk.Frame.__init__(
import tkinter as tk
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
label = tk.Label(self, text="This is the log in page ")
username=tk.Entry(self)
label.pack(side="top", pady=30, fill="both")
username.pack()
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
label = tk.Label(self, text="This is the register page")
label.pack(side="top", pady=30,fill="both")
class Page3(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
label = tk.Label(self, text="This is the game page ") #+user
label.pack(side="top",pady=30, fill="both")
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
p1 = Page1(self)
p2 = Page2(self)
p3 = Page3(self)
buttonframe = tk.Frame(self)
container = tk.Frame(self)
buttonframe.pack(side="left", fill="x", expand=False)
buttonframe.configure(bg="red")
container.pack(side="top", fill="both", expand=True)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p3.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(buttonframe, text="Log In", width=8, command=p1.lift)
b2 = tk.Button(buttonframe, text="Register",width=8, command=p2.lift)
b3 = tk.Button(buttonframe, text="Play Game",width=8, command=p3.lift)
b1.pack(padx=10,pady=10)
b2.pack(padx=10,pady =10)
b3.pack(padx=10,pady=10)
p1.show()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("400x400")
root.mainloop()
您需要提供一种机制,使每个页面都可以访问其他页面。您还需要确保需要访问的数据作为实例属性可用 控制器 通常,前者是通过通常所称的控制器来完成的。在这种情况下,它将是
MainView
,或者是一个新类。由于MainView
负责创建页面,因此它还可以负责为每个页面提供访问权限,这可以通过在创建页面时保存对页面的引用来实现
它看起来像这样:
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.p1 = Page1(self)
self.p2 = Page2(self)
self.p3 = Page3(self)
...
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
...
self.username=tk.Entry(self)
...
class Page3(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
self.label = tk.Label(self, text="")
self.label.pack(side="top",pady=30, fill="both")
def show(self):
user = self.controller.p1.username.get()
self.label.configure(text=f"This is the game page for {user}")
self.lift()
在每个页面中使用控制器
这些页面被赋予了对MainView
实例的引用,因此它们可以使用该引用来获取所需的数据。它看起来像这样:
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.p1 = Page1(self)
self.p2 = Page2(self)
self.p3 = Page3(self)
...
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
...
self.username=tk.Entry(self)
...
class Page3(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
self.label = tk.Label(self, text="")
self.label.pack(side="top",pady=30, fill="both")
def show(self):
user = self.controller.p1.username.get()
self.label.configure(text=f"This is the game page for {user}")
self.lift()
当您在每个页面中重复该模式时,每个页面都可以通过控制器访问其他页面:self.controller.p1
,self.controller.p2
,等等。这样,Page3
就可以使用类似于self.controller.p1.username
的内容访问Page1
的用户名
这是在不同对象之间共享数据的基本机制
约束条件
请注意,在创建第3页时,用户没有机会填写用户名,因此用户名将为空。您必须添加一些逻辑才能知道用户何时登录
解决这个问题的一个简单方法是为每个页面提供一个show
方法。show
方法负责提升页面并更新其小部件。它可能看起来像这样:
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.p1 = Page1(self)
self.p2 = Page2(self)
self.p3 = Page3(self)
...
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
...
self.username=tk.Entry(self)
...
class Page3(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
self.label = tk.Label(self, text="")
self.label.pack(side="top",pady=30, fill="both")
def show(self):
user = self.controller.p1.username.get()
self.label.configure(text=f"This is the game page for {user}")
self.lift()
然后需要修改按钮以调用show
方法:
b1 = tk.Button(..., command=self.p1.show)
b2 = tk.Button(..., command=self.p2.show)
b3 = tk.Button(..., command=self.p3.show)
总结
拥有控制器是协调对象之间通信的方便方式。每个对象不必与所有其他对象直接链接,它们只需要对控制器的引用。然后,控制器成为与其他小部件直接连接的唯一对象
这不是视图/控制器模式的最佳实现,但希望它能提供基本概念的概念。您需要保留对
tk.Entry
和所有页面
对象的引用。使用self.username=tk.Entry(self)
代替username=tk.Entry(self)
。这样,您以后可以使用self.username
访问它,并且您可以使用self.username.get()
获得tk.Entry
的内容。感谢您的回答和Bryan的完整解释。明亮的我不理解添加行self.controller=args[0]。我想通过阅读您的其他帖子,更好的方法是创建一个类,将共享数据保存在列表中?