我正在学习使用Tkinter使用python创建简单的GUI。我目前正在使用python文档作为参考(link)。
我要做的第一件事是理解那里的示例代码。我特别关注这段代码,它创建了一个带有两个按钮的对话框,一个用于在控制台上打印,另一个用于关闭程序:
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 init语句创建),但我不明白为什么使用该init名称创建主屏幕。我认为这是一个惯例,但是当我为'main'更改'init'时,按钮没有放在屏幕上,所以我不知道主屏幕是否必须始终使用该名称创建,或者我是谁做的那里有些不对劲。
我也不明白为什么每个函数都是使用(self)创建的(这意味着什么?)或者为什么.mainloop最后被调用(我想开始整个程序)当我没有看到任何类型的main时循环在示例代码中的任何位置定义。
我对对象如何工作有一个基本的了解,但我发现python在处理这些事情时有点混乱。我已经查看了关于这个的python文档,但它对我来说似乎有点模糊。
任何类型的链接到更具体的文档(比我正在使用的python更模糊的东西)将不胜感激。
您的问题似乎与课程有关。
基本上,只要创建该类的实例,就会调用类的__init__
方法。
在代码中创建的实例的示例是:
app = Application(master=root)
这意味着您的类必须被称为“应用程序”,尽管您没有包含该部分。
app现在是Application类的'instance'
。它是一个类对象,通过它您可以访问类方法(类中的函数)和它的类属性(类中的变量)。
名称__init__
不是一个约定,并将其称为其他东西将意味着它不再提供相同的功能。请记住,它是在您创建实例(或实例化)类时执行的(app = Application()
),而不是像任何其他方法一样专门调用它。它“初始化”类,使用您指定的任何代码设置它,因此它几乎在您使用它之前就已经准备好了。
self
花了我一点时间来掌握。 self
这个词实际上是一个约定,技术上你可以在那里使用任何一个词,但你永远不应该这样做,否则你将被最近的程序员骂。然而,这个词必须在那里,它应该是'self'
。为什么?它有什么作用?好...
当您实例化(创建实例)类时,如上所述,并且您想要使用类方法等,您需要一种方法让任何特定实例将自己与任何其他实例区分开来,它只是一种引用自身的方式(因此,自我这个词。所以类属性给出'self.
'前缀,类方法作为规则给出'self'
作为第一个参数。我的理解是,尽管你实际上只编写了一个Application类,但每次你创建一个新的实例,app1,app2,app3,无论如何,它们都有专门引用它们的指针,由self提供,所以当你是使用其中一个并访问方法等,您的实际类知道您正在处理哪一个。
如果我正在使用你的应用程序实例,app
,并想使用该类的属性(变量),我只会说app.attribute
并访问一个方法,app.method
。在这种情况下,我根本不必使用自我。但是,要调用一个方法,或在类本身的代码中引用一个属性,它是self.attribute
和self.method(args)
(注意self是前缀,而不是当你从类中调用方法时的arg。)
如果不是很清楚,我很抱歉。这些都是难以解释的事情,我也在学习自己。希望这个对你有帮助。
自我是因为代码在“类”形式内,所以当你使用它时,你在“对象样式”的领域,所以他们总是使用自己的属性,有关更多信息,请查看Python Object Oriented的这个链接
如果我没错,__ init__也必须对对象的使用做一些事情,所以有必要使用这个__init__以使事情有效。
关于mainloop,这是一个名为mainloop()的函数,你将从Tkinter导入,这是在开始时完成的,没有任何东西将以它应该的方式显示,如果你工作或尝试使用pygame,你会看到他们也以类似的方式使用这个mainloop的东西,我认为它应该以每秒一定数量的帧数继续更新屏幕显示。
顺便说一下,你会发现Tkinter用来做同样事情的不同方式,至少我已经看过3种方式:一种是你的榜样,一种非常有组织的风格;第二个是所有代码都按逻辑顺序但似乎有点笨拙的;第三个类似于您的示例代码,但另一个扭曲。因此,您必须尝试不同的样式,以便学习不同的技巧。
当您从类创建对象时,您'实例化'该类。执行此操作时,将执行__init__
方法。把__init__
想象成'初始化'。
当你写的时候
app = Application(master=Tk())
您通过创建一个名为Application
的类对象来实例化app
类。
通过传入Tk()
,您的类继承了Tk
类中的方法,该类为您的类提供了Tk()
类(按钮,标签,复选框等)的相同功能。
self
是类对象,在你的情况下是app
。在每个类方法中总是传递对象的引用似乎是多余的或不必要的,但是python需要这样,所以习惯于总是使用self
。