参考资料:
1.官方文档:docs
在编写python GUI程序前,需要决定使用哪个GUI平台。所谓平台,就是图形组件的一个特定集合,可以通过 GUI工具包(一些python模块)进行访问。
平台是炊具,而GUI工具包就像食材,能吃但是我们不能直接吃。操作炊具,搞定食材,天经地义。
常用的 GUI工具包有很多,python自带Tkinter工具包(库)。
我们编写的Python代码会调用Tkinter,Tkinter封装了访问Tk的接口;Tk是一个图形库,支持多个操作系统,使用Tcl语言开发;Tk会调用操作系统提供的本地GUI接口,完成最终的GUI。所以,我们的代码只需要调用Tkinter提供的接口(炊具、工具包)就可以了。
所谓的调用就是调用上级提供的接口(函数参数?)。
用Tkinter编程的步骤如下:
例1:
# -*- coding:utf-8 -*-
#导入Tkinter的所有内容
from Tkinter import *
#从Frame派生一个Application类,Frame是所有Widget(插件)的父容器
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
#pack()方法把Widget加入到父容器中,并实现布局
self.createWidgets()
#自动调用createWidgets()方法
#self代表的是父窗口(必须加上父窗口),而所有的Widgets都是在父窗口里面布局的
def createWidgets(self):
self.helloLabel = Label(self, text='Hello, world!')
self.helloLabel.pack()
#pack()方法把Widget加入到父窗口中,并实现布局
#pack()方法可有参数,如side,有四个参数可选:TOP(默认),下,左(side=Left),或右
self.quitButton = Button(self, text='Quit',command=self.quit)
#command:Function or method to be called when the button is clicked.
self.quitButton.pack()
#创建实例后,app自动布局,并调用self.createWidgets()
app = Application()
# 设置窗口标题:
app.master.title('Hello World')
# 主消息循环:
app.mainloop()
实际上,部件的命名不需要加上前面的' self. ',即像下面这样也是可以的:
# -*- coding:utf-8 -*-
#导入Tkinter的所有内容
from Tkinter import *
#从Frame派生一个Application类,Frame是所有Widget(插件)的父容器
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
#pack()方法把Widget加入到父容器中,并实现布局
self.createWidgets()
#自动调用createWidgets()方法
#self代表的是父窗口(必须加上父窗口),而所有的Widgets都是在父窗口里面布局的
def createWidgets(self):
helloLabel = Label(self, text='Hello, world!')
helloLabel.pack()
#pack()方法把Widget加入到父窗口中,并实现布局
#pack()方法可有参数,如side,有四个参数可选:TOP(默认),下,左(side=Left),或右
quitButton = Button(self, text='Quit',command=self.quit)
<span style="white-space:pre"> </span>#command:Function or method to be called when the button is clicked.
quitButton.pack()
#创建实例后,app自动布局,并调用self.createWidgets()
app = Application()
# 设置窗口标题:
app.master.title('Hello World')
# 主消息循环:
app.mainloop()
但是这样就无法保证方法之间的沟通,像下例:
例2:
# -*- coding:utf-8 -*-
from Tkinter import *
import tkMessageBox
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
nameInput = Entry(self,bg='black',fg='white')
nameInput.pack()
alertButton = Button(self, text='Hello', command=self.hello)
alertButton.pack()
def hello(self):
name = nameInput.get() or 'world'
#get()是Entry()的方法之一,获得输入信息(字符串)
tkMessageBox.showinfo('message','Hello, %s' % name)
#message是按下弹出Button后弹出的消息对话框的标题,这一项必须有
#后面的内容就是弹框具体显示的内容
# create the application
app = Application()
# 设置窗口标题:
#
# here are method calls to the window manager class
#
app.master.title('hello')
# 主消息循环:
app.mainloop()
这段程序就无法成功运行,原因在于
hello()方法中无法识别nameInput,就无法调用nameInput.get()方法:
# -*- coding:utf-8 -*-
from Tkinter import *
import tkMessageBox
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.nameInput = Entry(self,bg='black',fg='white')
self.nameInput.pack()
self.alertButton = Button(self, text='Hello', command=self.hello) #这两行的self. 可以省略,不影响,但是上两行一定不能省
self.alertButton.pack()
def hello(self):
name = self.nameInput.get() or 'world'
#get()是Entry()的方法之一,获得Entry中现有的信息(字符串)
tkMessageBox.showinfo('message','Hello, %s' % name)
#tkMessageBox.FunctionName(title, message [, options])单独使用,无需在createWidgets()中定义
#message是按下弹出Button后弹出的消息对话框的标题,这一项必须有
#后面的内容就是弹框具体显示的内容
# create the application
app = Application()
# 设置窗口标题:
#
# here are method calls to the window manager class
#
app.master.title('hello')
# 主消息循环:
app.mainloop()
所以,为保险起见,所有部件的命名,前面务必加上 “ self. ”(self是个变量,是创建的实例的名字,所以可以沟通各方法,这也是各方法之间传递self参数的原因)。
补充:
from Tkinter import *
def changeRelief():
reliefList = ['flat','raised','sunken','groove','ridge']
global reliefIndex
label.config(relief=reliefList[reliefIndex%len(reliefList)])
reliefIndex += 1
def changeColor(event):
colorList = ['red', 'blue','yellow']
global colorIndex
label.config(fg=colorList[colorIndex%len(colorList)])
colorIndex += 1
reliefIndex = 0
colorIndex = 0
root = Tk() # Create a root toplevel window
label = Label(root,text="Welcome to python")
button1 = Button(root, text = "relief",command=changeRelief)
#command:Function or method to be called when the button is clicked.
button2 = Button(root,text = "color")
button2.bind("<Button-1>",changeColor)
#拆分这句的含义:鼠标左击(<Button-1>) button2这个Button实例,触发处理函数changeColor,至于处理函数做了什么那时处理函数的事
#command和bind是事件触发处理函数的两种方式(所谓事件,指的是一个动作,如左击Button,鼠标光标进入/离开控件widget区域等)
label.pack()
button1.pack(side=LEFT,anchor=CENTER, expand=YES)
button2.pack(side=LEFT,anchor=CENTER, expand=YES)
root.mainloop() # Create an event loop