Python 模块化较大的tkinter程序
我用tkinter设计了一个GUI。我把它建在一个班级里。我通常使用的结构是创建一个框架并将我所有的小部件打包到其中。然后,当我需要显示一个不同的屏幕时,我销毁该框架并调用一个函数,该函数创建一个新的父框架和新的小部件来打包到其中。这里有一个简单的例子来说明这个结构Python 模块化较大的tkinter程序,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我用tkinter设计了一个GUI。我把它建在一个班级里。我通常使用的结构是创建一个框架并将我所有的小部件打包到其中。然后,当我需要显示一个不同的屏幕时,我销毁该框架并调用一个函数,该函数创建一个新的父框架和新的小部件来打包到其中。这里有一个简单的例子来说明这个结构 将tkinter作为tk导入 类窗口(): 定义初始(自我,主): self.master=master 自身主几何(“300x300”) frame=tk.frame(self.master) frame.pack() 自组装主机
将tkinter作为tk导入
类窗口():
定义初始(自我,主):
self.master=master
自身主几何(“300x300”)
frame=tk.frame(self.master)
frame.pack()
自组装主机(机架)
def goto(自身、目标、帧):
frame.destroy()
frame=tk.frame(self.master)
frame.pack()
转到={
“main”:self.main,
“a”:自我。a,
“b”:self.b
}
转到[目的地](帧)
def干管(自身、机架):
标签(frame,text='Main').pack()
按钮(frame,text='Goto A',command=lambda:self.Goto('A',frame)).pack()
按钮(frame,text='Goto B',command=lambda:self.Goto('B',frame)).pack()
def a(自身,机架):
标签(frame,text='A').pack()
按钮(frame,text='Back to Main',command=lambda:self.goto('Main',frame)).pack()
def b(自身,机架):
标签(frame,text='B').pack()
按钮(frame,text='Back to Main',command=lambda:self.goto('Main',frame)).pack()
root=tk.tk()
窗口(根)
root.mainloop()
与顶级窗口相比,我更喜欢这种结构,因为我过去在使用它们时遇到过问题(窗口落后于其他打开的窗口、焦点问题等)。但我真的很怀念顶级windows如何轻松地构建模块,而不是将所有代码都放在一个脚本中。有没有一种方法可以在不使用Toplevel的情况下轻松地将这样的结构模块化?这将是伟大的组织和可读性。我尝试过使用不同的“屏幕创建”函数并将它们放在模块中,但我遇到了循环依赖性问题
main.py
import tkinter as tk
import module
class Window():
def __init__(self, master):
self.master = master
self.master.geometry('300x300')
frame = tk.Frame(self.master)
frame.pack()
self.main(frame)
def goto(self, destination, frame):
frame.destroy()
frame = tk.Frame(self.master)
frame.pack()
goto = {
'main': self.main,
'a': module.a,
}
goto[destination](frame)
def main(self, frame):
tk.Label(frame, text='Main').pack()
tk.Button(frame, text='Goto A', command=lambda: self.goto('a', frame)).pack()
if __name__ == '__main__': # ADDED
root = tk.Tk()
window = Window(root)
root.mainloop()
将tkinter作为tk导入
导入模块
类窗口():
定义初始(自我,主):
self.master=master
自身主几何(“300x300”)
frame=tk.frame(self.master)
frame.pack()
自组装主机(机架)
def goto(自身、目标、帧):
frame.destroy()
frame=tk.frame(self.master)
frame.pack()
转到={
“main”:self.main,
“a”:模块.a,
}
转到[目的地](帧)
def干管(自身、机架):
标签(frame,text='Main').pack()
按钮(frame,text='Goto A',command=lambda:self.Goto('A',frame)).pack()
root=tk.tk()
窗口=窗口(根)
root.mainloop()
模块.py
将tkinter作为tk导入
进口干管
def a(帧):
标签(frame,text='A').pack()
按钮(frame,text='Back to Main',command=lambda:Main.window.goto('Main',frame)).pack()
当我点击该按钮时,我会看到模块中内置的框架:
AttributeError:部分初始化的模块“module”没有属性“a”(很可能是由于循环导入)
您可以通过简单地添加一个
来避免由于循环导入而导致的部分初始化模块错误,方法是:在主脚本末尾附近的代码周围添加一个,如下所示(当module.py
导入代码时,它会阻止后面的语句执行)
main.py
import tkinter as tk
import module
class Window():
def __init__(self, master):
self.master = master
self.master.geometry('300x300')
frame = tk.Frame(self.master)
frame.pack()
self.main(frame)
def goto(self, destination, frame):
frame.destroy()
frame = tk.Frame(self.master)
frame.pack()
goto = {
'main': self.main,
'a': module.a,
}
goto[destination](frame)
def main(self, frame):
tk.Label(frame, text='Main').pack()
tk.Button(frame, text='Goto A', command=lambda: self.goto('a', frame)).pack()
if __name__ == '__main__': # ADDED
root = tk.Tk()
window = Window(root)
root.mainloop()
module.py(无重大变化)
“不使用Toplevel?”:不清楚您的意思是什么,您不使用Toplevel
小部件吗?“获取循环依赖”:您的示例没有使用任何自定义导入,您的问题并提供了一个解决方案。相关@stovfl:OP说他们更喜欢使用显示的代码,而不是使用Toplevel
,因此这就是为什么没有使用它的原因——问题是:“有没有一种方法可以在不使用Toplevel的情况下轻松地模块化这样的结构?”@martineau:关于这一点的答案是:Yes@stovfl:同意<代码>;
您所要做的就是将a
和b
移动到单独的文件中,然后导入它们。这就是你要问的吗?