Разобрался.
В примере на github показано взаимодействие двух окон, что несколько специфично, обычно большая часть действий выполняется в главном окне программы. Но поскольку там так задумано (в одном окне две кнопки, изменяющие значение лейбла в другом окне) для реализации независимых окон автору пришлось использовать окна Toplevel. Вот немного о них:
Марк Лутц Программирование на Python том I: Обычно окна Toplevel используются для реализации многооконных интерфейсов, а также модальных и немодальных диалогов. Они сохраняются до тех пор, пока не будут явно закрыты или пока создавшее их приложение не завершит работу.
Сколько я не пробовал менять параметры передачи ссылки на главное окно ничего не получалось, пока я не обратил внимание на метод root.withdraw() в файле main.py. Не смотря на название, оказалось, что он срывает окно:
withdraw() Removes the window from the screen (without destroying it). To redraw the window, use deiconify. When the window has been withdrawn, the state method returns “withdrawn”.
Но в примере он нужен, что бы скрыть пустое нефункциональное окно root, которое заменяют два независимых окна Toplevel. В моем случае - приложение будет однооконное, поэтому если убрать этот метод, то все сразу начинает работать.
Рабочий файл main.py выглядит так:
main.py
from tkinter import *
from controllers.MainController import Controller
if __name__ == '__main__':
root = Tk()
root.title("PyDOE-tk")
app = Controller(root)
root.mainloop()