我提倡面向对象的方法。这是我开始的模板:
# 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()
需要注意的重要事项是:
I don't use a wildcard import. I import the package as "tk", which requires that I prefix all commands with tk.. This prevents global namespace pollution, plus it makes the code completely obvious when you are using Tkinter classes, ttk classes, or some of your own.
The main application is a class. This gives you a private namespace for all of your callbacks and private functions, and just generally makes it easier to organize your code. In a procedural style you have to code top-down, defining functions before using them, etc. With this method you don't since you don't actually create the main window until the very last step. I prefer inheriting from tk.Frame just because I typically start by creating a frame, but it is by no means necessary.
如果你的应用程序有额外的顶层窗口,我建议将每个顶层窗口作为一个单独的类,从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在状态栏上放置一些东西。设置(“Hello, world”)。这允许您在组件之间定义一个简单的接口,有助于将耦合保持在最小。