相信刚学习使用Python进行GUI编程的时候,肯定都会听过Tkinter,毕竟是standard Python interface to the Tk GUI toolkit.用来写一些小程序还是很方便的。但如果是刚接触GUI编程的话肯定是被官方文档搞的有些懵,毕竟还没弄清楚套路。之前使用过Tkinter,但是有段时间没碰了,最近又要写个小程序需要再捡起来,本想着搜索下别人的文章迅速熟悉以下,但是搜索水平有限,并没有搜到合适的文章,往往都是怎么怎么弄一下,跑起来GUI形式的Hello World就完了,或者写一堆又不不提套路,反而不如去看编排好看一点的文档了。所以这里记录一下,当作自己的学习笔记,也希望能帮助到需要的人。

注: 以下所述运行环境都是Python2.7

先跑起来看看

tkinter初步小程序

很显然,像Tk()这种函数,都是从Tkinter导入的。Tk()运行会返回一个基本窗口组件,其实就是一个对象了。然后对这个对象进行一些操作就可以改变窗口的外观,例如绑定其他组件,改变Title什么的。最后调用mainloop方法,顾名思义,是启动主循环,展现出窗口。另外,Tkinter是事件驱动型的,例如遇到点击之类的事件,会进行一些反应,也就是用户看到的所谓的操作了。

下面一点点来说,首先来看看啥是组件以及如何绑定组件,看下面的代码:

#coding: utf-8
#Date: 2016.03
#Author: Huspy blog: https://www.mierhuo.com

from Tkinter import *

root = Tk()
root.title('觅而获')

w = Label(root, text="Hello, world!")
w.pack()

root.mainloop()

可见,中间实例化了一个Label对象,在Tkinter中称之为Label组件或者标签组件,然后实例化的时候有一些初始化参数,例如这个组建附着在那个组建上,像label组件顾名思义,肯定要有内容,所以也得送入相关参数,这里显然参数是命名为了text。最后相当于是搞定了组件的初始化,确认绑定到附着的组件,当然了也可以 不绑定,只不过就不会显示了,只会存在于内存中,只有绑定上去了才会显示。实际上,这里的所谓绑定,又和Tkinter的排版方式有关,后面细说。

这段代码运行效果如下图:

Python Tkinter组件例子

Tkinter使用套路小结

到这里基本上就已经清楚了,整个套路就是,先初始化一个基础窗口组件,然后初始化其他组件比如输入框,标签Label,按钮之类的,初始化好了之后在绑定在相应的窗口上,但是最终要显示的组建肯定是一级一级的最后绑定到了基础窗口组建上面,最后调用基础窗口组件的mainloop方法启动主循环,窗口就生成并且显示了。Tkinter GUI 软件的工作是基于事件驱动的,比如按钮被点击什么的,执行一些操作。最后要退出就点击窗口的叉叉或者调用基础窗口组件的quit()方法即可。

细说组件

在Tkinter里面有很多的组件可供选择使用,用以完成不同的任务。这里只是说一下套路,所以挑两个典型的用的最多的来说----Label组件和Button组件。

Label组件主要用来显示文字或者图片之类的,同时有着比较丰富的表现力,怎么样放进去表现呢?显然是在初始化的时候放进去并且设置表现方式。例如我要显示蓝色底的红色文字,并且想要控制一下宽和高,可以这么初始化Label组件:

t = Label(root, bg="blue", fg="white", text="www.mierhuo.com", width=40, height=2)
t.pack()

那么最终显示的时候,会是这个样子:

Python Tkinter Label组件

再比如,我想要显示图片,可以这样初始化:

p = PhotoImage(file="./baifeng.gif")
w = Label(root, image=p)
w.pack()

这里的PhotoImage是库里面的一个方法,用于读取图片并且封装成库其他组件、方法可以直接利用的通用型对象。这样实例化之后显示的时候如下图:

Python Tkinter Label组建放图片

再比如Button组件,就一般软件而言,显然要有文字显示,表明按钮的作用,并且点击之类的操作会出发一些程序动作,所以实例化的时候也是如此:

# 变色功能按钮
bt = Button(root, text="Blink", fg="green", command=Blink.changeColor)
bt.pack()
# 退出功能按钮
bt = Button(root, text="Quit", fg="red", command=root.quit)
bt.pack()

最终显示会是这个样子:

Python Tkinter Button组件

可见,按钮的表现力也还可以,还可以控制文本的颜色。所以,到这里就很清楚了,每个组件都有自己的作用,有自己独特的展现力,另外,初始化时有些资源需要先调用其他方法封装一下比如图片什么的才能加以使用。库的使用者只需要根据需要,合理使用即可。

细说Tkinter GUI布局排版方式

前面有提到,组件实例化之后是要调用pack()去绑定在父组件上面,并且一级一级最终绑定在调用mainloop()的窗口基础组件上面。这个所谓的绑定其实就是GUI布局,或者说通过这个方式进行界面的布局排版。

在Tkinter中,有三种布局方式,分别是:Grid、Pack、Place。其中Pack前面已经出现了很多次了,就pack而言,从前面的小例子就可以看到,似乎就是从上到下依次堆叠,当然,这是因为没有指定任何参数,默认是如此,其实pack的时候可以指定很多参数,比如对齐方式、填充方式、排布方向之类的。例如前面的例子如果pack的时候修改一下参数:

t = Label(root, bg="blue", fg="white", text="www.mierhuo.com", width=40, height=2)
t.pack(fill='x')

这里顺便演示一下place的效果:

bt_blink = Button(root, text="Blink", fg="green", command=Blink.changeColor)
bt_blink.place(relx=0.7, rely=0.7)

最终代码如下:

#coding: utf-8
#Date: 2016.03
#Author: Huspy blog: https://www.mierhuo.com

from Tkinter import *

root = Tk()
root.title('觅而获')

t = Label(root, bg="blue", fg="white", text="www.mierhuo.com", width=40, height=2)
t.pack(fill='x')

p = PhotoImage(file="./baifeng.gif")
w = Label(root, image=p)
w.pack()

class Blink():

    flag = 1

    @staticmethod
    def changeColor():
        if Blink.flag:
            t.config(fg='red', bg='green')
            Blink.flag = 0
        else:
            t.config(fg="white", bg="blue")
            Blink.flag = 1

bt_blink = Button(root, text="Blink", fg="green", command=Blink.changeColor)
bt_blink.place(relx=0.7, rely=0.7)

bt_quit = Button(root, text="Quit", fg="red", command=root.quit)
bt_quit.pack()


root.mainloop()

最终效果如下:

Python Tkinter布局效果演示

小结

相信到了这一步,Python Tkinter的各种套路都很清楚了,剩下的就是看文档熟悉各种组件、布局的使用方法,然后练习练习就能上手了。然而,Tkinter的文档似乎比较难找啊,对于合适的文档,我刚开始也是找了很久没找到,这里分享一下:effbot.org/tkinterbook/tkinter-index.htm#class-reference

另外,之前用Python写过一个辣鸡嗅探器,代码写的很辣鸡,不过界面也是用Tkinter做的,有兴趣的同学可以参考一下:

代码传送门(GitHub)

界面如下:

Tkinter做GUI的嗅探器

(其实大半年以前就打算写此文了,结果就开了个头然后一直没动,博客也一直没更新,真是明日复明日,明日何其多。以后一定要改掉这个坏习惯,每天坚持学习,坚持写博客记录,与君共勉!)