Python 在tkinter GUI中使用来自另一个类(不同页面)的变量
我有一个由不同页面组成的应用程序,这些页面都放在一个框架内(带有状态栏、菜单栏等),并堆叠在彼此的顶部。通过调用函数Python 在tkinter GUI中使用来自另一个类(不同页面)的变量,python,class,tkinter,Python,Class,Tkinter,我有一个由不同页面组成的应用程序,这些页面都放在一个框架内(带有状态栏、菜单栏等),并堆叠在彼此的顶部。通过调用函数lift,我可以将各个页面置于其他页面之上。(这是一个最低可行的示例,整个程序大约有2000行) 当我从菜单栏中调用p1.lift时,第1页显示在前面-当我尝试第2页上的“从”按钮时,它会告诉我未定义名称p2。我明白了,因为我在MainView类中只引用了Page2(self)作为p2 如果我将按钮命令更改为command=Page2(self).lift,则代码将运行,但按钮没有
lift
,我可以将各个页面置于其他页面之上。(这是一个最低可行的示例,整个程序大约有2000行)
当我从菜单栏中调用p1.lift
时,第1页显示在前面-当我尝试第2页上的“从”按钮时,它会告诉我未定义名称p2
。我明白了,因为我在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()
如果
p2
不存在,则不能使用command=p2.lift
——因为它试图在p2
中查找lift
,以分配给command=
,但找不到p2
因此,首先必须创建实例(在按钮中没有command=
),然后必须在按钮中分配command=
p1 = Page1(self)
p2 = Page2(self)
p1.buttonToP1['command'] = p2.lift
p2.buttonToP2['command'] = p1.lift
(command=p1.list
在Page2
中不会出现问题,因为执行时p1
已经存在,但我对两个按钮使用['command']
使代码相同)
这还意味着您必须将self.
用于self.buttonop1
,self.buttonop2
完整代码:
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()
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()
编辑:其他方法是将函数用作类中的方法。然后分配现有方法
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)
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()
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()
带着我的非CS背景,我已经走了很长一段路,但无论什么时候开始上课,我还是不明白。例如,我将类Page2的实例创建为p2,但我不知道(尽管谷歌搜索了这么多…)如何从另一个类中访问它。请阅读给定链接并关注
实例变量
“此处忽略一些重要概念”:将p2
定义为实例变量后,可以执行command=self.master.p2.lift
.master
是tkinter
对象中的默认引用属性。我投票决定关闭它,因为这个问题很可能只是因为缺乏基本的OOP(?)知识,我看不出它对其他人特别有用。