构建 tkinter 应用程序的最佳方式? [英] Best way to structure a tkinter application?

查看:29
本文介绍了构建 tkinter 应用程序的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的典型python tkinter程序的整体结构.

The following is the overall structure of my typical python tkinter program.

def funA():
    def funA1():
        def funA12():
            # stuff

    def funA2():
        # stuff

def funB():
    def funB1():
        # stuff

    def funB2():
        # stuff

def funC():
    def funC1():
        # stuff

    def funC2():
        # stuff


root = tk.Tk()

button1 = tk.Button(root, command=funA)
button1.pack()
button2 = tk.Button(root, command=funB)
button2.pack()
button3 = tk.Button(root, command=funC)
button3.pack()

funA funBfunC 将在用户点击按钮 1 时打开另一个带有小部件的 Toplevel 窗口,2、3.

funA funB and funC will bring up another Toplevel windows with widgets when user click on button 1, 2, 3.

我想知道这是否是编写 python tkinter 程序的正确方法?当然,即使我这样写它也会起作用,但这是最好的方法吗?这听起来很愚蠢,但当我看到其他人编写的代码时,他们的代码并没有被一堆函数弄得一团糟,而且大部分都是类.

I am wondering if this is the right way to write a python tkinter program? Sure, it will work even if I write this way, but is it the best way? It sounds stupid but when I see the codes other people written, their code is not messed up with bunch of functions and mostly they have classes.

是否有任何特定的结构是我们应该遵循的良好做法?在开始编写python程序之前,我应该如何计划?

Is there any specific structure that we should follow as good practice? How should I plan before start writing a python program?

我知道编程中没有最佳实践这样的东西,我也没有要求它.我只是想要一些建议和解释,让我在自学 Python 的过程中保持正确的方向.

I know there is no such thing as best practice in programming and I am not asking for it either. I just want some advice and explanations to keep me on the right direction as I am learning Python by myself.

推荐答案

我提倡面向对象的方法.这是我开始使用的模板:

I advocate an object oriented approach. This is the template that I start out with:

# 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()

需要注意的重要事项是:

The important things to notice are:

  • 我不使用通配符导入.我将包导入为tk",这要求我在所有命令前加上 tk..这可以防止全局命名空间污染,而且当您使用 Tkinter 类、ttk 类或您自己的一些类时,它使代码完全显而易见.

  • 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.

主要应用是一个类.这为您的所有回调和私有函数提供了一个私有命名空间,并且通常可以更容易地组织您的代码.在程序风格中,您必须自上而下编写代码,在使用函数之前定义函数,等等.使用这种方法,您不需要,因为直到最后一步您才真正创建主窗口.我更喜欢从 tk.Frame 继承,因为我通常从创建一个框架开始,但这绝不是必要的.

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 继承.这为您提供了上述所有相同的优点——窗口是原子的,它们有自己的命名空间,并且代码组织得很好.另外,一旦代码开始变大,它可以很容易地将每个放入自己的模块中.

If your app has additional toplevel windows, I recommend making each of those a separate class, inheriting from tk.Toplevel. This gives you all of the same advantages mentioned above -- the windows are atomic, they have their own namespace, and the code is well organized. Plus, it makes it easy to put each into its own module once the code starts to get large.

最后,您可能需要考虑为界面的每个主要部分使用类.例如,如果您正在创建一个带有工具栏、导航窗格、状态栏和主要区域的应用程序,您可以创建这些类中的每一个.这使您的主要代码非常小且易于理解:

Finally, you might want to consider using classes for every major portion of your interface. For example, if you're creating an app with a toolbar, a navigation pane, a statusbar, and a main area, you could make each one of those classes. This makes your main code quite small and easy to understand:

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") 在状态栏上放置一些东西.这允许您在组件之间定义一个简单的接口,有助于保持最小耦合.

Since all of those instances share a common parent, the parent effectively becomes the "controller" part of a model-view-controller architecture. So, for example, the main window could place something on the statusbar by calling self.parent.statusbar.set("Hello, world"). This allows you to define a simple interface between the components, helping to keep coupling to a minimun.

这篇关于构建 tkinter 应用程序的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆