为什么在python中编写Tkinter GUI时使用类


19

我主要使用python进行编程,并使用Tkinter编写了几个GUI,我见过的每个教程都建议为该GUI定义和使用一个类,但是我的GUI可以仅使用过程而完美运行,而无需使用类。

为什么要上课?在我看来,这似乎只是复杂性和不必要代码的额外一层。

Answers:


19

为什么要上课?因为它使工作变得容易,所以假设您知道如何进行面向对象的编程,并假设您正在编写一个平凡的GUI。使用对象可以使您轻松地将代码分为自包含的模块化单元,而将代码模块化通常被认为是最佳实践。

GUI编程很容易采用面向对象的样式,因为GUI完全由对象组成-标签,按钮,滚动条,文本区域等。由于您已经在使用对象,因此将代码组织成更大的对象是有意义的。工具栏是一个对象,状态栏是一个对象,导航窗格是一个对象,主区域是一个对象,每个笔记本选项卡是一个对象,依此类推。

即使您的代码不是很复杂,从更实际的角度来看,它也可以让您在文件中比正在调用的函数定义更早地定义绑定和回调,我认为这很有意义。

例如,考虑一个简单的示例(假设已将tkinter导入为import tkinter as tk(python3)或import Tkinter as tk(python2):

def quit(event=None):
    sys.exit()
root = tk.Tk()
label = tk.Label(root, text="Hello, world")
label.pack()
label.bind("<1>", quit)
root.mainloop()

对我来说,该代码流是完全错误的。我必须先定义quit方法,然后再引用它,并且根窗口的创建和对mainloop的调用由所有其他代码分隔。

但是,通过使用类,我可以按照更自然的顺序编写代码:

class MyWindow(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Hello, world")
        label.pack()
        label.bind("<1>", self.quit)
    def quit(self, event=None):
        sys.exit()

root = tk.Tk()
MyWindow(root).pack()
root.mainloop()

GUI的主体位于文件的顶部,并且支持代码在文件的下面。现在,当然,您可以使用函数来实现很多相同的事情。但是我认为,类使这一切变得容易一些。

另一个优点是,我现在可以轻松更改包含窗口,而不必更改“主”窗口的任何内容(反之亦然)。也就是说,我可以在主GUI上添加边框或一个完整的新部分,但是不必在MyWindow内触摸任何一行代码。将此与可能需要更改label.pack()语句的过程代码以及UI中所有其他小部件的pack(或网格)语句进行对比。

但是,使用面向对象的方法来编写良好,干净,可维护的代码不是必需的。它可以是,但它也可能导致糟糕的代码。归根结底,面向对象的方法只是一种工具。是否使用它以及是否正确使用它取决于许多因素。因此,对于您和编写的代码而言,一种功能样式完全可以接受。我确实认为您会发现,随着您的程序变得越来越复杂,面向对象的方法将使组织和维护代码变得更加容易。


为什么在第二个示例中使用框架?您是否不能像在第一个示例中那样避免这种情况?在类中使用Frame背后有什么秘密吗?
multigoodverse '16

2
框架只是为了方便。从Frame继承没有秘密。我本来可以继承object或继承任何其他类,但是无论如何我通常最终都会创建一个框架。如果我将所有内容都放在框架中,则使类成为框架是有意义的。。
Bryan Oakley

1
很有道理,谢谢!另外,我看到其他人在变量前使用了self,但我看到您使用的是label=tk.Label()代替的东西 self.tk.Label()。那是款式选择吗?下面是使用自我的例子:python-textbok.readthedocs.org/en/1.0/...
multigoodverse

1
@BryanOakley,我想您打算在MyWindow .__ init__的以下行中使用父级而不是root:“ label = tk.Label(root,text =” Hello,world“)”
user3885927

1
@ user3885927:是的!哇,有人花了将近三年时间才注意到这一点。尽管不是parent,而是self,因为类本身是一个框架。谢谢!
布莱恩·奥克利
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.