Я защищаю объектно-ориентированный подход. Это шаблон, с которого я начинаю:
# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
<create the rest of your GUI here>
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Важные вещи, на которые стоит обратить внимание:
Я не использую импорт подстановочных знаков. Я импортирую пакет как «tk», который требует, чтобы я поставил перед всеми командами префикс tk.
. Это предотвращает глобальное загрязнение пространства имен, а также делает код совершенно очевидным, когда вы используете классы Tkinter, классы ttk или некоторые другие.
Основное приложение - это класс . Это дает вам личное пространство имен для всех ваших обратных вызовов и частных функций, и, как правило, упрощает организацию вашего кода. В процедурном стиле вы должны кодировать сверху вниз, определять функции перед их использованием и т. Д. С помощью этого метода вы этого не делаете, поскольку вы фактически не создаете главное окно до самого последнего шага. Я предпочитаю наследовать tk.Frame
только потому, что обычно начинаю с создания фрейма, но это ни в коем случае не является необходимым.
Если в вашем приложении есть дополнительные окна верхнего уровня, я рекомендую сделать каждый из них отдельным классом, унаследованным от tk.Toplevel
. Это дает вам все те же преимущества, что и упомянутые выше: окна являются атомарными, у них есть собственное пространство имен, а код хорошо организован. Кроме того, он позволяет легко помещать каждый в отдельный модуль, когда код начинает увеличиваться.
Наконец, вы можете рассмотреть возможность использования классов для каждой основной части вашего интерфейса. Например, если вы создаете приложение с панелью инструментов, панелью навигации, строкой состояния и основной областью, вы можете создать каждый из этих классов. Это делает ваш основной код довольно маленьким и легким для понимания:
class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.statusbar = Statusbar(self, ...)
self.toolbar = Toolbar(self, ...)
self.navbar = Navbar(self, ...)
self.main = Main(self, ...)
self.statusbar.pack(side="bottom", fill="x")
self.toolbar.pack(side="top", fill="x")
self.navbar.pack(side="left", fill="y")
self.main.pack(side="right", fill="both", expand=True)
Поскольку все эти экземпляры имеют общего родителя, родительский элемент фактически становится частью «контроллера» в архитектуре модель-представление-контроллер. Так, например, главное окно может поместить что-то в строку состояния, вызвав вызов self.parent.statusbar.set("Hello, world")
. Это позволяет вам определить простой интерфейс между компонентами, помогая поддерживать связь с минимальным.