Defendo uma abordagem orientada a objetos. Este é o modelo com o qual começo:
# 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()
As coisas importantes a serem observadas são:
Eu não uso uma importação de curinga. Eu importo o pacote como "tk", o que exige que eu prefixe todos os comandos com tk.
. Isso evita a poluição global do espaço para nome, além de tornar o código completamente óbvio quando você está usando as classes Tkinter, ttk ou algumas de sua preferência.
A principal aplicação é uma classe . Isso fornece um espaço de nome privado para todos os seus retornos de chamada e funções privadas, e geralmente facilita a organização do seu código. Em um estilo processual, é necessário codificar de cima para baixo, definindo funções antes de usá-las, etc. Com esse método, você não cria, pois na verdade não cria a janela principal até a última etapa. Prefiro herdar tk.Frame
apenas porque normalmente começo criando um quadro, mas não é de forma alguma necessário.
Se seu aplicativo tiver janelas adicionais de nível superior, recomendo que cada uma delas seja uma classe separada, herdada de tk.Toplevel
. Isso oferece as mesmas vantagens mencionadas acima - as janelas são atômicas, possuem seu próprio espaço para nome e o código é bem organizado. Além disso, facilita a inserção de cada um em seu próprio módulo assim que o código começa a aumentar.
Por fim, você pode considerar o uso de classes para todas as partes principais da sua interface. Por exemplo, se você estiver criando um aplicativo com uma barra de ferramentas, um painel de navegação, uma barra de status e uma área principal, poderá criar cada uma dessas classes. Isso torna seu código principal bem pequeno e fácil de entender:
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)
Como todas essas instâncias compartilham um pai comum, o pai se torna efetivamente a parte "controladora" de uma arquitetura de controlador de exibição de modelo. Assim, por exemplo, a janela principal pode colocar algo na barra de status chamando self.parent.statusbar.set("Hello, world")
. Isso permite definir uma interface simples entre os componentes, ajudando a manter o acoplamento no mínimo.