6. GUI编程之 tkinter
我们之前都是在写命令行程序,都是在黑框命令行里面玩耍,从这篇开始,我们就要接触真正的GUI编程了。
-
什么是GUI?
图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口),通俗的说,就是电脑上那些有界面的,通过键鼠操作的程序。 -
什么是tkinter呢?
tkinter是Python中自带的GUI库,它的优点是简单。除了tkinter之外,Python还有其他的图形库,但需要额外的安装。实际上,做一些小工具类的软件,tkinter足够胜任。
我们先运行下面的代码,看看效果吧
import tkinter as tk
word_dict = {
"meet": "v.会面", "family": "n.家庭",
"read": "v.阅读,读", "grandfather": "n.祖父,外祖父",
"grandmother": "n. 祖母,外祖母", "father": "n.父亲",
"mother": "n.母亲", "brother": "n.兄弟", "sister": "n.姐妹",
"hi": "喂,你好", "same": "a.相同的",
"flat": "n.套房,公寓", "all": "a.&pron.所有的",
"live": "v.&n.住,生活"
}
def query():
global input_str, display
word = input_str.get()
val = word_dict.get(word)
if val:
display["text"] = val
else:
display["text"] = "对不起,查不到"
root = tk.Tk()
input_str = tk.StringVar()
input_box = tk.Entry(root, textvariable=input_str)
display = tk.Label(root)
btn = tk.Button(root, text="查询", command=query)
input_box.pack(padx=10, pady=10)
btn.pack()
display.pack(pady=10)
root.mainloop()
这里先说一下关于导入库的问题,我们在第一行使用了一个新的语法import tkinter as tk
,这里的as
是起别名的意思。之前我们使用import random
这种方式导入模块时,有一个不爽的地方,每次调用模块里的函数时,我们都需要写模块名.函数名
的方式,假如模块名很长时,我们就需要多写很多字,因此我们需要更简洁一点的写法,这里就使用import as
的方式,在as
后面给模块临时取一个短小的别名,然后使用这个别名.函数
的方式调用。
6.1 从简单示例开始
我们之前已经接触过图形程序了,我们通常做图形程序的第一步就是需要创建一个“画板”,或者说是一个窗口,以下代码中,调用tkinter
模块的Tk()
构造函数即可实现我们的需求,而mainloop()
函数我们前面已经讲过了,在图形程序所有代码的最后,必须调用该函数,以使程序不要立刻退出,而是等待用户操作。
import tkinter as tk
root = tk.Tk()
root.mainloop()
有了窗口,我们还需要能与用户交互的各种元素,比如按钮,比如输入框等等,在tkinter
模块中,这些元素不需要我们自己去画,该库早已将常用的这些元素封装成了一个个组件,这些组件就像一个个积木,形状各异,我们要做的就是了解这些组件,然后发挥创造力,将这些“小积木”合理的放置在窗口面板里面就好了。
6.2 tkinter的小组件
- 按钮
先让我们来学习第一个组件——按钮。要想有个按钮,第一步肯定是创建它,那么第二步就是安放它。
import tkinter as tk
root = tk.Tk()
# 创建一个按钮,第一个参数指明想要放置的地方
btn = tk.Button(root, text="我是按钮")
# 将这个按钮放到窗口面板里
btn.pack()
root.mainloop()
要特别注意,每一个小组件的第一个参数都表示想要放置的地方,如上代码,root
变量代表的正是我们的窗口面板,指明将按钮放置在窗口面板上面。这里只是指明想要放置的地方,真正放置的代码是调用组件自身的pack()
函数,如不调用pack()
函数,放置的逻辑就不会生效。
- 标签
按钮我们很容易理解,那么标签是什么呢?标签其实就是一块用来显示文字或者图片的区域。假如我们要显示很多文字,那就必须先创建一个标签(Label
),然后把我们需要显示的文字放到标签这个组件里,最后再将标签放到窗口面板中。
import tkinter as tk
root = tk.Tk()
# 创建一个按钮
btn = tk.Button(root,text="我是按钮")
# 将这个按钮放到窗口面板里
btn.pack()
# 创建一个标签
label = tk.Label(root,text="你好!我是标签,我的英文名字叫Label")
# 将这个标签组件放到窗口面板里
label.pack()
root.mainloop()
- 输入框
输入框是很常见的一种组件,这里我们列出来的是单行文本框,即只能显示一行的那种输入框,通常这种输入框用于输入密码账户之类的操作。
import tkinter as tk
root = tk.Tk()
# 创建一个按钮
btn = tk.Button(root, text="我是按钮")
# 将这个按钮放到窗口面板里
btn.pack()
# 创建一个标签
label = tk.Label(root, text="你好!我是标签,我的英文名字叫Label")
# 将这个标签组件放到窗口面板里
label.pack()
# 创建一个单行输入框
box = tk.Entry(root)
box.pack()
root.mainloop()
6.3 组件的属性
组件在创建时可以传入各种属性,例如btn = tk.Button(root,text="我是按钮")
这行代码,我们在创建按钮时,传入了text
属性,这个属性代表按钮里面显示的文本,我们这里是传入了一句话。实际上,tkinter
中的小组件有非常多的属性,而这些属性也不需要死记硬背,还记得我们前面说过的吗,不知道不记得随时查文档!
除了text
,我们这里设置一些其他的属性,在创建Label
时,传入foreground
属性,给它的值是red
,运行后可以看到标签里面的文字变成红色了,这里foreground
是前景色,我们还可以传入背景色background
,令其background="blue"
看看效果。
label = tk.Label(root,foreground="red", text="你好!我是标签,我的英文名字叫Label")
上面的属性设置都是在创建组件时传入参数进行设置,其实我们还可以在创建之后去设置组件属性。当我们在创建时无法确定该属性的值时,我们就可以在之后去设置。比如说要在标签中显示的文本,创建标签时无法确定应该显示什么内容,只有当用户操作之后才能确定显示的文本内容。
import tkinter as tk
root = tk.Tk()
# 创建一个按钮
btn = tk.Button(root,text="我是按钮")
# 将这个按钮放到窗口面板里
btn.pack()
# 创建一个标签
label = tk.Label(root,foreground="red",background="blue")
# 设置标签的text属性
label["text"] = "你好!我是标签,我的英文名字叫Label"
# 将这个标签组件放到窗口面板里
label.pack()
# 创建一个单行输入框
box = tk.Entry(root)
box.pack()
root.mainloop()
如上,label["text"] = "你好!我是标签,我的英文名字叫Label"
,通过组件变量加中括号的形式去设置属性,这种写法与我们学过的字典数据结构非常相似。
6.4 按钮的响应
当我们点击按钮时,肯定是为了触发一个行为,从程序的角度说,就是需要响应用户的点击。
import tkinter as tk
def onclicke():
print("我被点击了")
root = tk.Tk()
# 创建一个按钮,并将按钮的点击与onclicke函数关联
btn = tk.Button(root, text="我是按钮", command=onclicke)
# 将这个按钮放到窗口面板里
btn.pack()
root.mainloop()
运行上面的代码后,点击我们创建的按钮,可以看到命令行里输出了我被点击了
这句话,这说明我们每次点击按钮时,onclicke
会被调用。onclicke
函数为是什么会被调用呢?原因就在于我们将按钮的command
属性的值设置为了onclicke
函数的函数名。command
属性就是用来将按钮被点击的事件与某个函数相关联的。一旦按钮被点击,则关联的函数就会被调用。
6.5 跟踪值的变化
输入框组件是用来接收用户输入的值的,那么我们如何获取用户输入的值呢?这里就需要用到Entry
的textvariable
属性了。
import tkinter as tk
def onclicke():
print("我被点击了")
global val
print(val.get())
root = tk.Tk()
# 创建一个按钮,并将按钮的点击与onclicke函数关联
btn = tk.Button(root, text="按钮", command=onclicke)
# 将这个按钮放到窗口面板里
btn.pack()
# 创建一个StringVar对象,用于跟踪输入框中的值
val = tk.StringVar()
entry = tk.Entry(root, textvariable=val)
entry.pack()
root.mainloop()
我们运行上述代码后,在输入框中输入内容,然后点击按钮,会看到命令行中打印出了输入框中的内容,这说明我们成功获取到了输入框中的内容。
看到代码的18行,我们创建了一个StringVar
的对象,string是字符串的意思,而StringVar
对象正是用来跟踪输入框中的文本内容的。这里要特别注意一点,与我们input
函数相似,通常单行文本框中接收的内容都是字符串,哪怕你输入的是整数!然后我们将创建出来的StringVar
对象的变量赋值给Entry
的textvariable
属性,到这里大功告成了,以后不管你在输入框中输入什么内容,我们都可以通过StringVar
对象的变量val
去调用get()
函数获得。这里就相当于将StringVar
对象与输入框中的内容绑定了。
学完了这些,我们再去看本章开始的词典程序代码就很容易理解了,这里只有一个地方稍加说明一下,pack()
函数的作用是将小组件放置到指定的地方,因此pack()
函数中也可以传入一些参数来控制放置的行为,例如input_box.pack(padx=10, pady=10)
,这里的padx=10
就表示在输入框的x轴方向(即左右两边各)留下10个单位像素的边距,pady
自然是y轴方向了。如果不传这两个参数,则输入框与按钮紧紧挨在一起,很不美观。
最后,本章学习了一些不同以往的概念,知识量也相对较多,因此建议大家学习的时候最好对照视频观看,特别是不太理解的时候。如果大家想学习更多关于tkinter的知识,可以查看我之前写过的 相关博客
请关注公众号:编程之路从0到1
进入公众号观看本章相关视频讲解,不容错过