0
0 комментариев

Пытаюсь реализовать шаблон MVC для приложения по примеру

https://github.com/li360/tkinter-mvc

В классе, отвечающим за создание главного окна приложения не знаю какие параметры использовать, — не отображаются элементы окна.

В примере 2 окна обмениваются данными, поэтому у них родительский класс выбран Toplevel. Но Toplevel не позволяет использовать вложенные элементы, такие как меню, ttk.Notebook и пр. и его рекомендуется использовать для диалоговых окон.

Как я понимаю, что происходит:

  1. В main.py создается объект контроллера, ему передается ссылка на главное окно приложения, созданное с помощью root = Tk() => app = Controller(root).
  2. В сонтроллере MainController.py создается объект окна self.view_main_window = ViewMainWindow(root) которому, в свою очередь, передается ссылка на главное окно приложения уже из класса контроллера.
  3. 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 1:
Выполнил рекомендации из первого комментария. Если сделать файл исполняемым, как в примере ниже, то все работает. Отображается окно с кнопкой и текстом.
Так я это и так понимаю, ведь у меня и вопрос сформулирован: какие параметры нужно передать из файла точки запуска через контроллер, что бы окно появилось с содержимым.

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


Добавить комментарий