Class 从一个类访问另一个类中的变量时出现问题(tkinter GUI-导航栏)

Class 从一个类访问另一个类中的变量时出现问题(tkinter GUI-导航栏),class,oop,tkinter,navigationbar,class-variables,Class,Oop,Tkinter,Navigationbar,Class Variables,Im使用此代码显示一个导航栏,允许我在当前显示的主页之间切换: import tkinter as tk class App(tk.Tk): def __init__(self,*args,**kwargs): tk.Tk.__init__(self, *args, **kwargs) self.geometry("600x400") container = tk.Frame(self) contain

Im使用此代码显示一个导航栏,允许我在当前显示的主页之间切换:

import tkinter as tk

class App(tk.Tk):
    def __init__(self,*args,**kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.geometry("600x400")
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(1, weight=1)

        self.mainframes = {}

        for F in (Mainframe1, Mainframe2):
            frame = F(container, self)
            frame.grid(row=0,column=1,sticky="nswe")
            self.mainframes[F] = frame

        navigationbar = NavigationbarFrame(container, self)
        navigationbar.grid(row=0, column=0, sticky="nswe")

        self.show_frame(Mainframe1)

    def show_frame(self, cont):
        frame = self.mainframes[cont]
        frame.tkraise()

class NavigationbarFrame(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg="green")

        # self.mainframe1_self = app.mainframes[Mainframe1]
        # self.mainframe2_self = app.mainframes[Mainframe2]
        # tk.Button(self, text=self.mainframe1_self.pagename, command=lambda: controller.show_frame(Mainframe1)).grid(row=0, column=0, sticky="w", pady=5, padx=10)
        # tk.Button(self, text=self.mainframe2_self.pagename, command=lambda: controller.show_frame(Mainframe2)).grid(row=1, column=0, sticky="w", pady=5, padx=10)

        tk.Button(self, text="Page 1", command=lambda: controller.show_frame(Mainframe1)).grid(row=0, column=0, sticky="w", pady=5, padx=10) #to be removed
        tk.Button(self, text="Page 2", command=lambda: controller.show_frame(Mainframe2)).grid(row=1, column=0, sticky="w", pady=5, padx=10) #to be removed

class Mainframe1(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent, bg="yellow")
        tk.Label(self, text="this is Page 1",bg="yellow").grid(row=0,column=0,padx=20,pady=20)
        self.pagename = "Page 1"

class Mainframe2(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent, bg="grey")
        tk.Label(self, text="this is Page 2", bg="grey").grid(row=0, column=0, padx=20, pady=20)
        self.pagename = "Page 2"


app = App()
mainframe1_self = app.mainframes[Mainframe1]

print(app.mainframes)
print(mainframe1_self)
print(mainframe1_self.pagename)

app.mainloop()
现在我正在尝试编辑NavigationbarFrame()类中的按钮。我想从类Mainframe1()、Mainframe2()中访问按钮的文本[请参阅#outcommented代码]

由于某些原因,我得到以下错误:

Traceback (most recent call last):
  File "C:\Users\....py", line 53, in <module>
    app = App()
  File "C:\Users\....py", line 19, in __init__
    navigationbar = NavigationbarFrame(container, self)
  File "C:\Users\....py", line 32, in __init__
    self.mainframe1_self = app.mainframes[Mainframe1]
NameError: name 'app' is not defined
不幸的是,这将我引向了下一个问题:
不知何故,我创建的两个按钮都将我带到了第2页。我不明白为什么会这样,因为第一个按钮应该包括:

command = lambda: controller.show_frame(Mainframe1)
command = lambda: controller.show_frame(Mainframe2)
第二个按钮应包括:

command = lambda: controller.show_frame(Mainframe1)
command = lambda: controller.show_frame(Mainframe2)

有人知道我的错误在哪里吗?
谢谢

在构建
App
时,
App
不存在。因为您使用的是面向对象的代码,所以不应该依赖于全局变量。最后,您的
NavigationbarFrame
不应该试图访问
应用程序中的
大型机
变量。尽管它的编码方式是一个公共变量,但其他类确实不应该依赖它——它将页面与控制器紧密耦合

相反,您应该在
App
中有一个方法为您返回给定的帧。然后可以使用该方法获取对其他帧的引用

首先,将
get_page
定义为类似于
show_frame
,但不是显示框架,而是返回框架:

class App(tk.Tk):
    ...

    def get_frame(self, cont):
        frame = self.mainframes[cont]
        return frame
最后,使用此方法获得帧。由于
controller
App
的实例,您可以这样做:

class NavigationbarFrame(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg="green")

        mainframe1 = controller.get_frame(Mainframe1)
        mainframe2 = controller.get_frame(Mainframe2)

        b1 = tk.Button(self, text=mainframe1.pagename, command=lambda: controller.show_frame(Mainframe1))
        b2 = tk.Button(self, text=mainframe.pagename, command=lambda: controller.show_frame(Mainframe2))

        b1.grid(row=0, column=0, sticky="w", pady=5, padx=10)
        b2.grid(row=1, column=0, sticky="w", pady=5, padx=10)

请出示完整的回溯。我将把它插入帖子!请不要把问题完全换成另一个话题。一个好问题应该只问一件事。这个网站上有很多关于在循环中创建按钮或命令的问题。它工作得非常好!非常感谢你!现在我尝试添加带有for循环的按钮,但是命令效果有一些问题。我编辑了这篇文章来提供一些细节。也许你现在也犯了我的错误?