我从之前的问题中改编了这段代码,该问题巧妙地保留了导航框架,但会根据按下的按钮更改内容框架。登录页面有一个入口小部件。我想将它的值(“Paul”说)转移到 Play Game 框架,例如,它说“这是游戏页面 Paul”。有了这个特殊的设置,如果有人可以提供帮助,我不知道如何实现它。
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()
答案 0 :(得分:0)
您需要提供一种机制,每个页面都可以访问其他页面。您还需要确保您需要访问的数据可用作实例属性。
通常,前者是通过通常称为控制器的东西来完成的。在这种情况下,这将是 MainView
,或一个新类。由于 MainView
负责创建页面,因此它还可以负责授予对每个页面的访问权限,这可以通过在创建时保存对它们的引用来实现。
看起来像这样:
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.p1 = Page1(self)
self.p2 = Page2(self)
self.p3 = Page3(self)
...
页面被赋予了对 MainView
实例的引用,因此他们可以使用它来获取所需的数据。它看起来像这样:
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.controller = args[0]
...
self.username=tk.Entry(self)
...
当您在每个页面中重复该模式时,每个页面都可以通过控制器访问其他所有页面:self.controller.p1
、self.controller.p2
等。这样,Page3
可以访问Page1
的用户名,类似于 self.controller.p1.username
。
这是在不同对象之间共享数据的基本机制。
请注意,在您创建第 3 页时,用户将没有机会填写用户名,因此用户名将为空。您必须添加一些逻辑才能知道用户何时登录。
该问题的一个简单解决方案是为每个页面提供一个 show
方法。 show
方法负责提升页面并更新它的小部件。它可能看起来像这样:
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)
拥有控制器是协调对象之间通信的便捷方式。不是每个对象都必须与所有其他对象直接链接,它们只需要对控制器的引用。然后,控制器成为与其他所有小部件直接连接的唯一对象。
这不是视图/控制器模式的最佳实现,但希望它提供了基本概念的概念。