python - 在 tkinter GUI 中使用来自另一个类(不同页面)的变量
问题描述
我有一个由不同页面组成的应用程序,这些页面都放在一个框架内(带有状态栏、菜单栏等)并相互堆叠。通过调用函数lift
,我可以将相应的页面置于其他页面之上。(这是一个最小的可行示例,完整的程序大约有 2000 行)
当我p1.lift
从菜单栏调用时,第 1 页会出现在前面 - 当我从第 2 页上的按钮尝试相同的操作时,它会告诉我name p2 is not defined
. 我明白了,因为我只Page2(self)
在 MainView 类中引用为p2
.
如果我将按钮命令更改为command=Page2(self).lift
,代码运行,但按钮不执行任何操作。我还尝试通过partial
模块传递带参数的函数,但仍然没有运气。
只有当我定义一个自定义函数时它才会起作用,例如通过 name 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()
解决方案
你不能使用command=p2.lift
if p2
doesn't exist - 因为它试图找到lift
分配p2
给command=
它却找不到p2
所以首先你必须创建实例(没有command=
按钮),然后你必须创建command=
按钮。
p1 = Page1(self)
p2 = Page2(self)
p1.buttonToP1['command'] = p2.lift
p2.buttonToP2['command'] = p1.lift
(command=p1.list
inPage2
没有问题,因为p1
它在执行时已经存在,但我使用['command']
两个按钮使代码相同)
这也意味着你必须使用self.
for self.buttonToP1
,self.buttonToP2
完整代码:
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)
self.buttonToP1 = tk.Button(self, text='Go to Page 2')
self.buttonToP1.pack(fill=tk.X)
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.buttonToP2 = tk.Button(self, text='Go to Page 1', bg='yellow')
self.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)
p1.buttonToP1['command'] = p2.lift
p2.buttonToP2['command'] = p1.lift
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()
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()
编辑:其他方法是将您的函数用作类中的方法。然后你分配现有的方法command=self.change
,所以它没有问题
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
buttonToP1 = tk.Button(self, text='Go to Page 2', command=self.change)
buttonToP1.pack(fill=tk.X)
def change(self):
p2.lift()
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
buttonToP2 = tk.Button(self, text='Go to Page 1', command=self.change, bg='yellow')
buttonToP2.pack(fill=tk.X)
def change(self):
p2.lift()
完整代码:
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=self.change)
buttonToP1.pack(fill=tk.X)
def change(self):
p2.lift()
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
buttonToP2 = tk.Button(self, text='Go to Page 1', command=self.change, bg='yellow')
buttonToP2.pack(fill=tk.X)
def change(self):
p2.lift()
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()
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()
推荐阅读
- google-api - Intermittent "The API developer key is invalid" error
- java - 如何自定义spring boot嵌入式tomcat线程池?
- authentication - 包含“图像处理”和“用户身份验证”步骤的应用程序的前端和后端开发
- angular - 如何在离子 4 中使用 forEach?
- javascript - 根据浏览器语言和地理位置显示特定的 div 或内容
- postgresql - PSQLEXCEPTION:从数据源“FEDSER”收到意外的错误代码“55000”。关联的文本和标记是“此 ResultSet 已关闭”。
- git - 在不直接访问 Git 存储库的情况下恢复本地不存在的提交
- python - Python:I/O 文件如果循环不起作用。CSV单元格值不比较
- java - org.hibernate.exception.GenericJDBCException:无法准备语句
- android - 我有一个执行网络调用的 Kotlin 异步任务。我想传递任务应该在运行时执行的方法