tkinter-将条目小部件值传递给另一个类

时间:2021-05-07 18:11:17

标签: python tkinter

我从之前的问题中改编了这段代码,该问题巧妙地保留了导航框架,但会根据按下的按钮更改内容框架。登录页面有一个入口小部件。我想将它的值(“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()

1 个答案:

答案 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.p1self.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)

总结

拥有控制器是协调对象之间通信的便捷方式。不是每个对象都必须与所有其他对象直接链接,它们只需要对控制器的引用。然后,控制器成为与其他所有小部件直接连接的唯一对象。

这不是视图/控制器模式的最佳实现,但希望它提供了基本概念的概念。