【发布时间】:2020-01-08 19:49:53
【问题描述】:
我有一个由不同页面组成的应用程序,这些页面都放置在一个框架内(带有状态栏、菜单栏等)并相互堆叠。通过调用函数lift,我可以将相应的页面置于其他页面之上。 (这是一个最小的可行示例,完整的程序大约有 2000 行)
当我从菜单栏中调用 p1.lift 时,第 1 页会显示在前面 - 当我从第 2 页上的按钮尝试相同操作时,它会告诉我 name p2 is not defined。我明白了,因为我只在 MainView 类中将Page2(self) 引用为p2。
如果我将按钮命令更改为command=Page2(self).lift,代码会运行,但按钮不执行任何操作。我还尝试通过partial 模块传递带参数的函数,但仍然没有运气。
只有当我定义一个自定义函数时它才会起作用,例如名称为LiftP2,它只做类本身可以做的事情——p2.lift()。
我想知道是否有人可以向我解释为什么我需要使用该解决方法以及如何以与从菜单相同的方式访问它...因为我没有编写这些类(而是从其他 SO 答案生成它们: )) 显然在这里错过了一些重要的概念,我很乐意为所描述的问题提供任何帮助。
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)
buttonToP1 = tk.Button(self, text='Go to Page 2', command=LiftP2)
buttonToP1.pack(fill=tk.X)
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
buttonToP2 = tk.Button(self, text='Go to Page 1', command=LiftP1, bg='yellow')
buttonToP2.pack(fill=tk.X)
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
global p1,p2
p1 = Page1(self)
p2 = Page2(self)
mainMenu = tk.Menu(self)
root.config(menu=mainMenu)
mainMenu.add_command(label='Navigate to Page 1', command=p1.lift)
mainMenu.add_command(label='Navigate to Page 2', command=p2.lift)
container = tk.Frame(self)
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)
p1.show()
def LiftP1():
p1.lift()
def LiftP2():
p2.lift()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.title('Testapplication v01')
root.wm_geometry('%dx%d+%d+%d' % (300, 200, 100, 100))
root.mainloop()
【问题讨论】:
-
我的非 CS 背景已经走得很远了,但是每当课程开始发挥作用时,我还是不明白。这里例如我将 Page2 类的实例创建为 p2,但我不知道(尽管谷歌搜索...)如何从另一个类中访问它。
-
阅读给定的链接并关注
Instance variable -
“错过了一些重要的概念”:将
p2定义为Instance variable后,您可以执行command=self.master.p2.lift。.master是tkinter对象中的默认引用属性。 -
我投票结束这个问题,因为这个问题很可能只是由于缺乏基本的 OOP (?) 知识而引起的,而且我看不出它对其他人特别有用。