一、认识Python和GUI开发
1、认识Python
诞生:1989年圣诞节荷兰程序员Guido van Rossum在阿姆斯特丹开始开发Python,目标是创建一种易读、简洁且开放的语言,弥补ABC语言的不足。Python单词原意为蟒蛇,但命名灵感源自喜剧剧集《Monty Python's Flying Circus》,Python一名的创作意与原意无关,但在后来Python语言的图标上也有了蟒蛇的图案,象征着Python的灵活性和强大的功能。
发展:(大版本更新)
1994年:Python 1.0 发布
2000年:Python 2.0 里程碑更新
2008年:Python 3.0(Python 3000) 发布
至今:Python 3.0 版本
语言:Python是一种高级、解释型、通用编程语言,代码简洁易读,支持跨平台开发,拥有丰富的生态,多范式支持,开源免费,应用领域广泛,功能强大。在众多编程语言排行榜上,Python都位居前列(TIOBE 2025评分23.88%)。
代码:代码风格简洁、明确、优雅,Python以可读性为核心的设计哲学,形成了一套独特的代码风格规范(PEP 8),核心原则(Python之禅)有优美胜于丑陋,简洁胜于复杂,可读性至上。"代码是写给人看的,只是顺带让机器执行" —— Guido van Rossum。其中编译器强制性的规则是代码严格缩进。
2、认识GUI
图形用户界面(Graphical User Interface) 允许用户通过视觉组件(按钮、输入框、窗口等)与程序交互,替代命令行操作。
核心价值:降低使用门槛(非技术用户友好),提升操作效率(可视化反馈),增强数据展示能力(图表、多媒体)
Python库:
库名 | 学习难度 | 功能强度 | 适用场景 |
---|---|---|---|
Tkinter | ★☆☆☆☆ | ★★☆☆☆ | 简单工具、快速原型 |
PyQt/PySide | ★★★★☆ | ★★★★★ | 商业级复杂应用 |
wxPython | ★★★☆☆ | ★★★★☆ | 需原生外观的跨平台应用 |
Kivy | ★★★★☆ | ★★★★☆ | 移动端/触控应用 |
从表中可以看出Python中的Tkinter库简单易学,但功能性一般,适用于简单工具,桌面端简单应用的开发。
二、Python中的Tkinter库
Tkinter 是 Python 的标准 GUI 工具包,作为 Python 内置库,它提供了快速创建跨平台图形界面的能力。
Tkinter库的核心要素:组件、布局、事件
特点介绍
特性 | 说明 |
---|---|
内置无需安装 | Python 标准库(import tkinter ) |
跨平台 | 支持 Windows/macOS/Linux |
轻量级 | 安装包仅增加约 1-2 MB |
易学性 | 语法简单,文档丰富 |
组件丰富 | 20+ 基础控件 + 扩展组件 |
核心组件体系
1、基础组件
组件 | 功能 | 示例创建 |
---|---|---|
Label | 文本/图像显示 | Label(root, text="Hello") |
Button | 可点击按钮 | Button(root, text="OK", command=func) |
Entry | 单行文本输入 | Entry(root, width=20) |
Text | 多行文本编辑 | Text(root, height=10) |
Frame | 容器控件 | Frame(root, borderwidth=2) |
2、高级组件
组件 | 用途 |
---|---|
Listbox | 选项列表 |
Canvas | 绘图区域(支持图形、图像) |
Menu | 菜单栏/右键菜单 |
Scale | 滑块控件 |
Treeview | 树形表格(需 ttk) |
适用场景与功能限制
适用:
-
小型工具开发(文件处理/数据转换)
-
教学演示
-
快速原型验证
-
硬件控制界面(树莓派项目)
限制:
-
界面美观度有限
-
复杂表格、图表支持弱
-
无硬件加速图形
概括总结
Tkinter是Python GUI开发的瑞士军刀
-
零成本快速构建基础界面
-
通过
ttk
实现现代化外观 -
事件驱动模型处理用户交互
-
特别适合小型工具开发和硬件项目界面
三、走进GUI开发——Tkinter库
1、导入Tkinter库
Tkinter作为Python的内置库,直接导入即可。(注:本文代码以Python3.0版本为例)
import tkinter
但通常为了调用函数方便,常写作:
import tkinter as tk
另外,我们可以通过以下方法查看Tkinter库的版本:
import tkinter
print(tkinter.TkVersion)
2、Tkinter界面坐标模式
坐标系:Tkinter生成的界面中坐标系如下图所示,以界面容器左上角顶点为坐标原点(0 , 0),x轴为水平轴,正方向水平向右;y轴为竖直轴,正方向竖直向下。界面坐标系是在界面容器中的坐标系,不包括标题栏、菜单栏、滑框栏等。
其中,坐标单位是以1个像素为单位的。
Tkinter窗口如下图所示,其中标题栏和界面容器是窗口与生俱来的,菜单栏和滑块栏是创建的。
3、Tkinter中颜色规则
Tkinter中颜色有两种表示方式:英文字母表示和十六进制表示。
Tkinter中如果不指定颜色,那么为默认的浅灰色,叫作SystemButtonFace
(1)英文字母表示
基础颜色(16种)
颜色名 | 中文名 | 颜色名 | 中文名 |
---|---|---|---|
aliceblue | 爱丽丝蓝 | antiquewhite | 古董白 |
aqua | 水色 | aquamarine | 碧绿色 |
azure | 天蓝色 | beige | 米色 |
bisque | 橘黄色 | black | 黑色 |
blanchedalmond | 杏仁白 | blue | 蓝色 |
blueviolet | 蓝紫色 | brown | 棕色 |
burlywood | 实木色 | cadetblue | 军蓝色 |
全部颜色(140种)
colors=[
'aliceblue', 'antiquewhite', 'antiquewhite1', 'antiquewhite2',
'antiquewhite3', 'antiquewhite4', 'aqua', 'aquamarine',
'aquamarine1', 'aquamarine2', 'aquamarine3', 'aquamarine4',
'azure', 'azure1', 'azure2', 'azure3', 'azure4', 'beige',
'bisque', 'bisque1', 'bisque2', 'bisque3', 'bisque4', 'black',
'blanchedalmond', 'blue', 'blue1', 'blue2', 'blue3', 'blue4',
'blueviolet', 'brown', 'brown1', 'brown2', 'brown3', 'brown4',
'burlywood', 'burlywood1', 'burlywood2', 'burlywood3', 'burlywood4',
'cadetblue', 'cadetblue1', 'cadetblue2', 'cadetblue3', 'cadetblue4',
'chartreuse', 'chartreuse1', 'chartreuse2', 'chartreuse3', 'chartreuse4',
'chocolate', 'chocolate1', 'chocolate2', 'chocolate3', 'chocolate4',
'coral', 'coral1', 'coral2', 'coral3', 'coral4',
'cornflowerblue', 'cornsilk', 'cornsilk1', 'cornsilk2', 'cornsilk3', 'cornsilk4',
'cyan', 'cyan1', 'cyan2', 'cyan3', 'cyan4',
'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgoldenrod1', 'darkgoldenrod2',
'darkgoldenrod3', 'darkgoldenrod4', 'darkgray', 'darkgreen', 'darkgrey',
'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkolivegreen1', 'darkolivegreen2',
'darkolivegreen3', 'darkolivegreen4', 'darkorange', 'darkorange1', 'darkorange2',
'darkorange3', 'darkorange4', 'darkorchid', 'darkorchid1', 'darkorchid2',
'darkorchid3', 'darkorchid4', 'darkred', 'darksalmon', 'darkseagreen',
'darkseagreen1', 'darkseagreen2', 'darkseagreen3', 'darkseagreen4', 'darkslateblue',
'darkslategray', 'darkslategray1', 'darkslategray2', 'darkslategray3', 'darkslategray4',
'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deeppink1',
'deeppink2', 'deeppink3', 'deeppink4', 'deepskyblue', 'deepskyblue1',
'deepskyblue2', 'deepskyblue3', 'deepskyblue4', 'dimgray', 'dimgrey',
'dodgerblue', 'dodgerblue1', 'dodgerblue2', 'dodgerblue3', 'dodgerblue4',
'firebrick', 'firebrick1', 'firebrick2', 'firebrick3', 'firebrick4',
'floralwhite', 'forestgreen', 'gainsboro', 'ghostwhite', 'gold',
'gold1', 'gold2', 'gold3', 'gold4', 'goldenrod',
'goldenrod1', 'goldenrod2', 'goldenrod3', 'goldenrod4', 'gray',
'green', 'green1', 'green2', 'green3', 'green4',
'greenyellow', 'grey', 'honeydew', 'honeydew1', 'honeydew2',
'honeydew3', 'honeydew4', 'hotpink', 'hotpink1', 'hotpink2',
'hotpink3', 'hotpink4', 'indianred', 'indianred1', 'indianred2',
'indianred3', 'indianred4', 'indigo', 'ivory', 'ivory1',
'ivory2', 'ivory3', 'ivory4', 'khaki', 'khaki1',
'khaki2', 'khaki3', 'khaki4', 'lavender', 'lavenderblush',
'lavenderblush1', 'lavenderblush2', 'lavenderblush3', 'lavenderblush4', 'lawngreen',
'lemonchiffon', 'lemonchiffon1', 'lemonchiffon2', 'lemonchiffon3', 'lemonchiffon4',
'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrod', 'lightgoldenrodyellow',
'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon',
'lightseagreen', 'lightskyblue', 'lightslateblue', 'lightslategray', 'lightslategrey',
'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen',
'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid',
'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise',
'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin',
'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab',
'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen',
'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru',
'pink', 'plum', 'powderblue', 'purple', 'red',
'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown',
'seagreen', 'seashell', 'sienna', 'silver', 'skyblue',
'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen',
'steelblue', 'tan', 'teal', 'thistle', 'tomato',
'turquoise', 'violet', 'wheat', 'white', 'whitesmoke',
'yellow', 'yellowgreen'
]
说明
-
大小写不敏感:所有颜色名称不区分大小写,
RED
、red
和Red
效果相同 -
系统支持:这些颜色名在Windows/macOS/Linux上均可使用
-
颜色变体:带数字后缀的颜色名(如
red1
到red4
)表示同色系的深浅变化 -
灰度表示:
gray
/grey
可互换,数字后缀表示灰度级别(gray0
=黑,gray100
=白) -
备用拼写:
gray
和grey
是等价的,dimgray
和dimgrey
也是等价的
(2)十六进制表示
十六进制颜色表示法(Hex Color Codes)是数字设计中最常用的颜色编码系统,广泛用于网页设计、图形软件和编程中(包括Tkinter)
基本结构
十六进制颜色代码由“#”符号+
6位字符组成,格式为:#RRGGBB
分段 | 含义 | 范围 | 说明 |
---|---|---|---|
RR | 红色分量 | 00 -FF | 00(最小) → FF(最大) |
GG | 绿色分量 | 00 -FF | 00(最小) → FF(最大) |
BB | 蓝色分量 | 00 -FF | 00(最小) → FF(最大) |
示例:
-
#FF0000
→ 纯红色(R:255, G:0, B:0) -
#00FF00
→ 纯绿色 -
#0000FF
→ 纯蓝色
字符编码原理
字符 | 十进制值 | 字符 | 十进制值 |
---|---|---|---|
0 | 0 | 8 | 8 |
1 | 1 | 9 | 9 |
2 | 2 | A | 10 |
3 | 3 | B | 11 |
4 | 4 | C | 12 |
5 | 5 | D | 13 |
6 | 6 | E | 14 |
7 | 7 | F | 15 |
计算原理:
每个颜色分量 = 第一位值 × 16 + 第二位值
示例:
#3A7B2F
的绿色分量 7B
→ 7×16 + 11×1 = 112 + 11 = 123
常见颜色速查表
颜色名称 | 十六进制 | 颜色名称 | 十六进制 |
---|---|---|---|
纯白 | #FFFFFF | 深灰 | #333333 |
纯黑 | #000000 | 浅灰 | #CCCCCC |
正红 | #FF0000 | 玫红 | #FF0077 |
草绿 | #00FF00 | 墨绿 | #008844 |
天蓝 | #0000FF | 靛蓝 | #4A0082 |
明黄 | #FFFF00 | 橘黄 | #FF8800 |
品红 | #FF00FF | 浅紫 | #CC99FF |
青色 | #00FFFF | 青绿 | #00AA88 |
通过掌握十六进制颜色表示法,可以精确控制界面视觉效果,创建专业级的GUI应用。
4、Tkinter中的窗口
窗口(Window)是 Tkinter 的基础容器,所有 GUI 组件都放置在窗口中。
Tkinter中窗口有两类,主窗口(Tk)和子窗口(Toplevel),其中,一个Python文件中可以有多个子窗口但只能有一个主窗口,否则可能会出现问题(但出现问题根据编译环境不同有时不是必然结果,也可能不出现错误,但根据规范不建议在一个Python文件中创建多个主窗口,因为这样会引起不稳定性),多个窗口可以同时显示在屏幕上;窗口的显示和事件的交互依赖事件循环mainloop()
,文件中必须包含,所有窗口共享同一个事件循环;子窗口也能创建自己的子窗口,子窗口依赖上一级窗口,当子窗口的上一级窗口被关闭时,子窗口也会被关闭。
特性 | 主窗口 (Tk() ) | 子窗口 (Toplevel() ) |
---|---|---|
数量限制 | 只能有1个 | 可以有多个 |
创建方式 | tk.Tk() | tk.Toplevel(parent) |
关闭影响 | 终止整个应用 | 只关闭自身 |
位置关系 | 底层窗口 | 显示在父窗口之上 |
生命周期 | 整个应用期间 | 独立于其他窗口 |
事件循环依赖 | 必须存在 | 依赖主窗口的事件循环 |
(1)创建主窗口(根窗口)
import tkinter as tk
root = tk.Tk()
root.mainloop()
(2)设置窗口属性
属性 | 方法 | 示例 |
---|---|---|
窗口标题 | title() | root.title("我的应用") |
窗口尺寸 | geometry("宽x高") | root.geometry("800x600") |
背景色 | configure(bg="颜色") | root.configure(bg="#F0F0F0") |
图标 | iconbitmap("图标路径") | root.iconbitmap("icon.ico") |
透明度 | attributes("-alpha", 0.0-1.0) | root.attributes("-alpha", 0.9) |
置顶 | attributes("-topmost", True) | root.attributes("-topmost", 1) |
全屏 | attributes("-fullscreen", True) | root.attributes("-fullscreen", True) |
注意:窗口尺寸中“geometry("宽x高")”的宽和高之间是小写字母“x”。
(3)窗口行为控制
功能 | 方法 | 示例 |
---|---|---|
禁止调整大小 | resizable(False, False) | root.resizable(0, 0) |
最小化窗口 | iconify() | root.iconify() |
恢复窗口 | deiconify() | root.deiconify() |
关闭窗口 | destroy() | root.destroy() |
设置最小/最大尺寸 | minsize() , maxsize() | root.minsize(400, 300) |
(4)窗口位置控制
tkinter界面在屏幕上的坐标系与在tkinter界面容器中的类似,也是以左上角为坐标原点,横纵轴也类似
设置窗口位置与设置窗口尺寸共用一个方法geometry("宽x高+x偏移+y偏移")
,例如geometry("800x600+400+300")表示创建一个像素大小尺寸为“800x600”的窗口,并将其放置在界面左上角距离屏幕左边缘“x”像素,距离屏幕上边缘“y”像素的位置。
如下面代码,先获取屏幕分辨率,让后将窗口居中放置。
# 获取屏幕尺寸
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 窗口居中
x = (screen_width - window_width) // 2
y = (screen_height - window_height) // 2
root.geometry(f"{window_width}x{window_height}+{x}+{y}")
以上使用的方法是正偏移方法,其中正偏移方法是以屏幕左边缘和屏幕上边缘为基准的,对于Tkinter界面来说是以左上角顶点为参考点的,那么负偏移方法则是以屏幕右边缘和屏幕下边缘为基准的,对于Tkinter界面来说是以右下角顶点为参考点的。
负偏移方法即geometry("宽x高-x偏移-y偏移")
,例如geometry("800x600-400-300")表示创建一个像素大小尺寸为“800x600”的窗口,并将其放置在界面右下角距离屏幕右边缘“x”像素,距离屏幕下边缘“y”像素的位置。
总结表格
参数 | 基准点 | 方向 | 示例 | 效果 |
---|---|---|---|---|
+X偏移 | 屏幕左边缘 | 向右为正 | +100 | 距左100像素 |
-X偏移 | 屏幕右边缘 | 向左为负 | -100 | 距右100像素 |
+Y偏移 | 屏幕上边缘 | 向下为正 | +50 | 距顶50像素 |
-Y偏移 | 屏幕下边缘 | 向上为负 | -50 | 距底50像素 |
参考点 | 窗口左上角 | - | - | 窗口定位的锚点 |
(5)mainloop()相关说明
在 Tkinter 中,创建窗口后不调用 mainloop()
有时也能看到窗口显示,但这不是可靠的行为,并且会导致程序功能不完整
不写mainloop()也能显示窗口的原因(了解即可)
-
Python 交互模式下的特殊行为:在 Python 的交互式环境(如 IDLE 或 IPython)中运行时,交互环境有自己的事件循环,可能临时接管了 Tkinter 的事件处理,但这不是 Tkinter 的正式工作方式,不可靠
-
某些 IDE 的辅助功能:像 PyCharm 这样的 IDE 可能在后台运行了部分事件处理,但当你将程序导出为独立脚本时,这种行为会消失
-
update()或update_idletasks()的间接调用:如果在创建窗口后调用了这些方法(可能通过其他组件间接触发),这些方法会处理部分待处理事件,可能使窗口短暂显示
不写mainloop()会出现什么问题
-
事件循环缺失
-
窗口可能显示,但无法响应任何事件
-
按钮点击、键盘输入、窗口关闭等操作都不会有效果
-
-
程序立即退出
-
在独立脚本中,没有 mainloop() 时程序会立即结束
-
窗口可能只闪现一下就关闭了
-
-
资源管理问题
-
没有事件循环,窗口无法正确释放资源
-
可能导致内存泄漏或程序无法正常终止
-
调用mainloop()相关说明
-
必须调用
mainloop()
:-
对于任何实际可用的 Tkinter 应用
-
确保窗口能正常响应用户交互
-
-
调用位置:
-
在设置好所有界面组件后调用
-
通常是脚本的最后一行有效代码
-
-
调用次数:
-
整个应用只需调用一次(在创建主窗口后)
-
所有窗口共享同一个事件循环
-
总结:虽然在某些特殊环境下不写 mainloop()
可能看到窗口显示,但这绝不是正确的做法。
5、Tkinter中的布局
6、Tkinter中的控件
控件 | 用途 |
Label | 标签控件,用来在窗口上显示文本和图片 |
Message | 消息控件,用来显示多行文本,与Label功能类似 |
Button | 按钮控件,用户可以点击按钮,点击事件将会传递给设置的回调函数 |
Entry | 文本输入框控件,用户可以输入文字,但只能在一行输入 |
Text | 多行文本输入框控件,用户可以输入多行文字,自由换行 |
Canvas | 画布控件,可以在上面显示基本图形、文字、图片 |
Frame | 框架控件,作为一个小容器,相当于给组件分组。 |
LabelFrame | 文字框架控件,和Frame不同的是,框架外面多了文本提示 |
Menu | 菜单控件,在窗口上显示菜单,或定义弹出式菜单。 |
Menubutton | 菜单按钮控件,是Button的样子,点击后弹出一个菜单。 |
Checkbutton | 多选按钮,用户可以勾选或取消勾选。 |
Radiobutton | 单选按钮,用户可以在同类的Radiobutton中选择一个,无法取消勾选 |
Listbox | 列表框组件,可以显示一个字符串的列表 |
Scrollbar | 滚动条控件,用来添加一个滚动条控制滚动 |
Scale | 尺度条控件,用来添加一个数字滑块,用户可以滑动调整数值。 |
Spinbox | 数字选值框控件,用户既可以输入数字,也可以按调节按钮调整数值。 |
OptionMenu | 选项菜单,用户可以从下拉菜单中选择一个值,但是不能自己输入。 |
PanedWindow | 分栏容器控件,和Frame类似,但是有更多的功能设定,比如用户可以调节大小 |
Toplevel | 上层窗口控件,可以定义某个窗口的子窗口。 |