У меня есть GUI, который я проектирую, используя tkinter. Я построил это внутри класса. Структура, которую я обычно использую, состоит в том, чтобы создать рамку и упаковать в нее все мои виджеты. Затем, когда мне нужно показать другой экран, я уничтожаю этот кадр и вызываю функцию, которая создает новый родительский кадр и новые виджеты для упаковки в него. Вот простой пример, поясняющий эту структуру.
import tkinter as tk
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': self.a,
'b': self.b
}
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()
tk.Button(frame, text='Goto B', command=lambda: self.goto('b', frame)).pack()
def a(self, frame):
tk.Label(frame, text='A').pack()
tk.Button(frame, text='Back to Main', command=lambda: self.goto('main', frame)).pack()
def b(self, frame):
tk.Label(frame, text='B').pack()
tk.Button(frame, text='Back to Main', command=lambda: self.goto('main', frame)).pack()
root = tk.Tk()
Window(root)
root.mainloop()
Я предпочитаю эту структуру Toplevel windows, потому что у меня были проблемы с ними в прошлом (windows отстает от других открытых windows вопросы фокуса и др. c). Но я очень скучаю по тому, как легко Toplevel 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()
root = tk.Tk()
window = Window(root)
root.mainloop()
module.py
import tkinter as tk
import main
def a(frame):
tk.Label(frame, text='A').pack()
tk.Button(frame, text='Back to Main', command=lambda: main.window.goto('main', frame)).pack()
Когда я нажимаю кнопку, которая приведет меня к рамке, встроенной в модуль, я получаю:
AttributeError: частично инициализированный модуль 'module' не имеет атрибута 'a '(скорее всего из-за кругового импорта)