关于python:__ init__在GUI中使用tkinter

__init__ in GUI with tkinter

我正在学习使用tkinter用python创建简单的gui。我目前正在使用python文档作为参考(link)。

我要做的第一件事是理解那里的示例代码。我特别关注这段代码,它创建了一个带有两个按钮的对话框,一个按钮用于在控制台上打印某些内容,另一个按钮用于关闭程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Tkinter import *

class Application(Frame):
    def say_hi(self):
        print"hi there, everyone!"

    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] ="QUIT"
        self.QUIT["fg"]   ="red"
        self.QUIT["command"] =  self.quit

        self.QUIT.pack({"side":"left"})

        self.hi_there = Button(self)
        self.hi_there["text"] ="Hello",
        self.hi_there["command"] = self.say_hi

        self.hi_there.pack({"side":"left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

我理解函数createWidgets将所有元素放置在屏幕中(以某种方式使用def in i t语句创建),但我不理解为什么使用该init名称创建主屏幕。我以为这是惯例,但当我更改了"main"的"in i t"时,按钮没有放在屏幕上,所以我不知道主屏幕是否必须总是用那个名称创建,或者是我做错了什么。

我也不明白为什么每个函数都是使用(self)创建的(这意味着什么?)或者为什么,当我在示例代码中没有看到任何定义的主循环时,在结尾调用main loop(我想启动整个程序)。

我对对象的工作方式有一个基本的了解,但是在处理类似的事情时,我发现Python有点混乱。我已经看过关于这个的python文档,但对我来说它似乎有点模糊。

任何指向更具体文档的链接(比我正在使用的Python文档不那么含糊)都将非常感谢。


你的问题似乎与课程有关。

基本上,类的__init__方法在创建该类的实例时立即调用。

在代码中创建的实例的一个示例是:

1
app = Application(master=root)

这意味着您的类必须称为"应用程序",尽管您没有包含该部分。

app现在是应用程序类的'instance'。它是一个类对象,通过它可以访问类方法(类内的函数)和类属性(类内的变量)。

名称__init__不是一个约定,将其称为其他名称意味着它不再具有相同的功能。记住,它是在创建一个实例(或实例化)该类时执行的。(app = Application()),而不是像其他方法一样通过调用它来执行的。它"初始化"类,用您指定的任何代码设置它,所以它几乎在您使用它之前就准备好了。

我花了一点时间才明白。self这个词实际上是一种惯例,从技术上讲,你可以在那里使用任何一个词,但是你不应该这样做,否则你会被最近的程序员骂。然而,这个词必须存在,它应该是'self'。为什么?它是做什么的?好。。。

当您实例化(创建类的实例)类时,如上面所述,并且您想要使用类方法等,您需要一种方法来让任何特定的实例将自己与任何其他实例区分开来,这只是一种引用自身的方法(因此是self一词)。因此,类属性被赋予'self.'前缀,类方法被赋予'self''作为规则的第一个参数。我的理解是,尽管您实际上只编写了一个应用程序类,但是每次创建一个新实例app1、app2、app3时,它们都有一些指针,它们都是特定地引用它们的,由self提供的,因此当您使用其中一个实例和访问方法等时,您的实际类知道您要处理的是哪个实例。

如果我使用您的应用程序实例app,并且想要使用该类的属性(变量),我只会说app.attribute并访问方法app.method。在那种情况下,我根本不需要使用自我。但是,要调用方法或引用类本身代码内的属性,它是self.attributeself.method(args)(请注意,在从类内实际调用方法时,self是前缀,而不是arg)。

如果不太清楚,我很抱歉。这些事情很难解释,我也在学习。希望能有所帮助。


当您从一个类创建一个对象时,您"实例化"这个类。执行此操作时,将执行__init__方法。把__init__看作"初始化"。

当你写的时候

1
app = Application(master=Tk())

您正在通过创建一个名为app的类对象来实例化Application类。

通过传入Tk()In,类继承了Tk类中的方法,从而使类具有与Tk()类相同的功能(按钮、标签、复选框等)。

self是类对象,在您的例子中是app。在每个类方法中总是传递对对象的引用似乎是多余的或不必要的,但是Python需要这样做,所以要习惯于总是使用self


self是因为代码在"class"形式中,所以当你使用"objects-style"时,它们总是使用带有self的属性,有关更多信息,请查看这个面向对象的python链接

如果我没有错的话,初始化也必须与对象的使用有关,因此有必要使用这个初始化来让事情正常工作。

关于mainLoop,这是一个名为mainLoop()的函数,您将从tkinter导入它,这个函数在开始时就完成了,没有这个函数,任何东西都不会以它应该的方式显示,如果您工作或尝试使用pygame,您会看到它们也以类似的方式使用这个mainLoop,它应该会不断更新ce上的屏幕显示。我想,每秒的帧数是多少。

顺便说一句,你会发现不同的方法,用特金特做同样的事情,至少我见过三种方法:一种是像你的例子,一种非常有组织的风格;第二种是所有代码都按逻辑顺序排列,但看起来有点笨拙;第三种是类似于你的例子代码,但有另一种扭曲。所以你必须尝试不同的风格,这样才能学到不同的技巧。