Пытаюсь реализовать шаблон MVC для приложения по примеру
https://github.com/li360/tkinter-mvc
В классе, отвечающим за создание главного окна приложения не знаю какие параметры использовать, - не отображаются элементы окна.
В примере 2 окна обмениваются данными, поэтому у них родительский класс выбран Toplevel. Но Toplevel не позволяет использовать вложенные элементы, такие как меню, ttk.Notebook и пр. и его рекомендуется использовать для диалоговых окон.
Как я понимаю, что происходит:
В main.py создается объект контроллера, ему передается ссылка на главное окно приложения, созданное с помощью root = Tk() => app = Controller(root).
В сонтроллере MainController.py создается объект окна self.view_main_window = ViewMainWindow(root) которому, в свою очередь, передается ссылка на главное окно приложения уже из класса контроллера.
MainView.py получает ссылку в конструкторе def init(self, parent), переименовывает self.master = parent. Дальше виджеты используют ее для определения своей принадлежности.
Это в теории, на практике, - после запуска окна нет, но и сообщений об ошибках тоже нет.
main.py
from tkinter import *
from controllers.MainController import Controller
if __name__ == '__main__':
root = Tk()
root.title("PyDOE-tk")
root.withdraw()
app = Controller(root)
root.mainloop()
controllers/MainController.py
from models.MainModel import Model
from views.MainView import ViewMainWindow
class Controller:
def __init__(self, root):
self.model = Model()
self.view_main_window = ViewMainWindow(root)
views/MainView.py
from tkinter import *
class ViewMainWindow(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.master = parent
self.frame = Frame()
self.frame.pack()
self.button = Button(self.frame, text="myButton")
self.button.pack(side=BOTTOM)
self.name = Label(self.frame, text='Label')
self.name.pack()
Если выбрать родительским классом Toplevel (как в примере на github), то окно показывается, но пустое:
class ViewMainWindow(Toplevel):
def __init__(self, parent):
Toplevel.__init__(self, parent)
self.master = parent
self.protocol('WM_DELETE_WINDOW', self.master.destroy)
self.frame = Frame()
self.frame.pack()
self.button = Button(self.frame, text="myButton")
self.button.pack(side=BOTTOM)
self.name = Label(self.frame, text='Label')
self.name.pack()
PS.Если сделать файл исполняемым, как в примере ниже, то все работает. Отображается окно с кнопкой и текстом.
Потому и вопрос: какие параметры нужно передать из файла точки запуска через контроллер, что бы окно появилось с содержимым.
from tkinter import *
class ViewMainWindow:
def __init__(self, parent):
self.master = parent
self.frame = Frame()
self.frame.pack()
self.button = Button(self.frame, text="myButton")
self.button.pack(side=BOTTOM)
self.name = Label(self.frame, text='Label')
self.name.pack()
self.master.mainloop()
root = Tk()
ViewMainWindow(root)
PS 2: Думал, что как то ссылка на главное окно не передается, ввел строку
print('type of root: ', type(parent), id(parent))
в main, контроллер и представление, оказалось, что ссылка на главное окно передается одна и та же:
type of root from main: <class 'tkinter.Tk'> 2774823903920
type of root from controller: <class 'tkinter.Tk'> 2774823903920
type of root from view: <class 'tkinter.Tk'> 2774823903920