Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python tkinter-将条目小部件值传递给另一个类_Python_Tkinter - Fatal编程技术网

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

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__(

我根据前面的一个问题改编了这段代码,该问题整洁地保留了一个导航框,但根据按下的按钮更改了内容框。登录页面有一个条目小部件。我想将它的值(“Paul”say)转移到Play游戏框架中,例如,它会说“这是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()

您需要提供一种机制,使每个页面都可以访问其他页面。您还需要确保需要访问的数据作为实例属性可用

控制器 通常,前者是通过通常所称的控制器来完成的。在这种情况下,它将是
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]。我想通过阅读您的其他帖子,更好的方法是创建一个类,将共享数据保存在列表中?