Hello World,编写一个Tkinter程序需要哪些基本步骤?
2020-10-13 by Vincent Ping前文《Python自带的GUI库Tkinter是否值得学习》介绍了Tkinter库,下面我们开始使用Tkinter开发第一个GUI程序,按照惯例,编写一个Hello World程序,不过是Tkinter版本。
import tkinter
root = tkinter.Tk()
label1 = tkinter.Label(root, text="Hello World!")
label1.pack()
root.mainloop()
上面 helloworld1.py 是最精简Tkinter版本的Hello World程序,运行该程序得到如下结果:
下面我们来解读下,同时进行一些简单的优化。
总体来说,可以将Tkinter程序的开发工作分成四个步骤:
1、创建并设置根窗口
开发一个GUI程序,如同画画一样,首先我们要有画布,其他所有的工作都在该画布上展开。
Tkinter程序中的画布就是根窗口。上面程序中第二行代码
root = tkinter.Tk()
就创建了一个画布。而最后一行代码
root.mainloop()
则运行该画布所承载的整个程序。
通过上面第二行代码生成画布窗口后,我们还可以设置该窗口的一些属性,比如窗口的title,窗口的尺寸大小,窗口是否可以变化大小等。我们可以添加如下代码:
root.title("Hello World") # 设置画布窗口的title
root.geometry("800x330") # 设置画布窗口的尺寸
root.resizable(0,0) # 设置画布窗口是否能变化大小,这里设置X和Y轴都不可改变
2、选择要显示的组件(widgets)并进行对应设置
画布有了,接下来需要决定用户在程序界面上会看到哪些功能模块,比如按钮、文本输入框、多选按钮、单选按钮、进度条等等。这些模块在Tkinter中叫组件(Widgets,也有叫“控件”的),可以把它们想象成Tkinter已经准备好的模块。这些模块如同积木一样,我们要做的就是按照需求选择相应的组件,并设置每个组件的属性。
上述程序中,我们就使用了一个标签Label组件,这个label1放置在根窗口root(亦即第一步中的“画布”)上,标签上的文本为“Hello World!”。
label1 = tkinter.Label(root, text="Hello World!")
这里,我们同样可以进一步设置该标签的一些属性,比如标签的背景颜色、高度,文本的字体、大小和颜色等。
label1 = tkinter.Label(root, text="Hello World!" bg='lightcyan', height=10, fg='black',font=("微软雅黑", 14))
3、组件的布局管理
完成组件的选择后,第三步我们要调整这些组件在程序中的位置和相互关系,比如是横向排列还是纵向,当程序窗口(画布)缩放时,组件本身如何变化,相互之间位置如何变化等等。Tkinter中,这个过程叫着布局管理(geometry management)。
在上述程序中,我们使用了最直接的布局管理方法pack():
label1.pack()
这里,pack()有一些参数可以设置,比如fill参数设置组件是否在X和Y轴方向填充空间,而expand参数则设置当组件所在窗口大小变化时,该组件是否相应扩展。
label1.pack(fill=tkinter.BOTH, expand=tkinter.YES)
到这里,我们看看先前的Hello World程序变成如下 helloworld2.py:
import tkinter
root = tkinter.Tk()
root.title("Hello World")
root.geometry("800x330")
root.resizable(0, 0)
label1 = tkinter.Label(root, text="Hello World!", bg="lightcyan", height=10, fg="black",font=("微软雅黑", 14))
label1.pack(fill=tkinter.BOTH, expand=tkinter.YES)
root.mainloop()
运行该程序,效果如下:
4、给组件编写交互功能
一个GUI程序的最大作用是我们可以和它进行交互,前面的组件的选择、设置和布局,最终都是为了让我们更好的与程序交互。
所以,在这一步,我们需要给模块和组件添加事件功能。例如,点击一个按钮时会有什么样的反应;用户选择一个单选或者多选项时,选择的内容如何保存和传递;用户通过文本框输入的数据又是如何保存和传递等等。Tkinter中,我们使用回调函数(callback)来进行事件绑定(event binding)。
后续我们会专门讨论回调函数的绑定,这里只通过给上述Hello World程序增加基本交互功能进行简单的说明。以下为 helloworld3.py :
import tkinter
root = tkinter.Tk()
root.title("Hello World")
root.geometry("800x330")
root.resizable(0, 0)
label_text = tkinter.StringVar()
label_text.set('Hello World!')
def set_chinese():
label_text.set("世界,你好!")
label1 = tkinter.Label(root, textvariable=label_text, bg="lightcyan", height=10, fg="black",font=("微软雅黑", 14))
label1.pack(fill=tkinter.BOTH, expand=tkinter.YES)
button1 = tkinter.Button(root, text='中 文', font=("宋体", 12), command=set_chinese)
button1.pack(side=tkinter.TOP, pady=10)
root.mainloop()
这里,我们首先创建了一个Tkinter变量label_text,并设置其初始值为“Hello World!”。
label_text = tkinter.StringVar()
label_text.set('Hello World!')
同时,在创建label1时,我们使用textvariable=label_text绑定,label1的文本就是label_text变量:
label1 = tkinter.Label(root, textvariable=label_text, bg="lightcyan", height=10, fg="black",font=("微软雅黑", 14))
接着,添加一个按钮组件button1,同时设置其点击回调函数为set_chinese:
button1 = tkinter.Button(root, text='中 文', font=("宋体", 12), command=set_chinese)
回调函数set_chinese的定义为:
def set_chinese():
label_text.set("世界,你好!")
也就是,当我们点击button1时,程序会调用set_chinese函数,该函数的作用是让label_text变量设置为“世界,你好!”。
最后,我们再通过布局管理方法pack()将button1添加到画布上。
button1.pack(side=tkinter.TOP, pady=10)
运行程序,界面如下:
当我们点击按钮时,显示内容变成:
点击“中文”按钮时,文本“Hello World!”会变成“世界,你好!”。可见,这个HelloWorld程序相比前面的例子增加了简单的交互功能,这个功能是通过将回调函数set_chinese与按钮button1的点击事件进行绑定实现的。
总结一下
本文介绍了编写Tkinter程序的几个基本步骤,大致是:
- 创建并设置根窗口
- 选择要显示的组件并进行对应设置
- 组件的布局管理
- 给组件编写交互功能
同时,通过三个HelloWorld程序,分别对这些步骤进行了简单介绍。后续将会针对这些步骤,作进一步的详细介绍。