Tkinter - 快速开始
安装
Tkinter 随 Python 一同发行。验证其是否可用:
终端
python -c "import tkinter; print(tkinter.TkVersion)"
# 应输出:8.6
⚠️ Linux 用户
在 Ubuntu/Debian 上,运行:sudo apt-get install python3-tk
你的第一个窗口
每个 Tkinter 应用程序都遵循相同的三步模式:
- 创建根窗口 ——
tk.Tk() - 在窗口内添加控件
- 启动事件循环 ——
root.mainloop()
first_window.py
import tkinter as tk
root = tk.Tk()
root.title("我的第一个应用")
root.geometry("400x300") # 宽度 x 高度
root.mainloop()
完整应用:温度转换器
temp_converter.py
import tkinter as tk
from tkinter import ttk
class TempConverter(tk.Tk):
def __init__(self):
super().__init__()
self.title("温度转换器")
self.resizable(False, False)
self.celsius = tk.StringVar(value="0")
self.fahrenheit = tk.StringVar(value="32")
self._build_ui()
self.celsius.trace_add("write", self._from_c)
self.fahrenheit.trace_add("write", self._from_f)
def _build_ui(self):
f = ttk.Frame(self, padding=20)
f.pack()
ttk.Label(f, text="°C").grid(row=0, column=1)
ttk.Entry(f, textvariable=self.celsius, width=10).grid(row=0, column=0)
ttk.Label(f, text=" = ").grid(row=0, column=2)
ttk.Entry(f, textvariable=self.fahrenheit, width=10).grid(row=0, column=3)
ttk.Label(f, text="°F").grid(row=0, column=4)
def _from_c(self, *_):
try: self.fahrenheit.set(f"{float(self.celsius.get())*9/5+32:.2f}")
except: pass
def _from_f(self, *_):
try: self.celsius.set(f"{(float(self.fahrenheit.get())-32)*5/9:.2f}")
except: pass
TempConverter().mainloop()
💡 基于类的应用
继承 tk.Tk 可以使你的代码组织更清晰,并且在应用规模扩大时保持良好的可扩展性。
这段代码实现了一个实时温度转换器,它会在输入摄氏温度或华氏温度时自动计算并更新另一个值。下面逐步分析:
1. 整体架构
class TempConverter(tk.Tk):
- 类继承自
tk.Tk,即应用主窗口本身就是一个完整的 Tkinter 应用程序。 - 这种面向对象的设计便于管理状态和方法,比面向过程的写法更易扩展。
2. __init__ 初始化方法
super().__init__()
self.title("温度转换器")
self.resizable(False, False)
super().__init__():调用父类tk.Tk的构造函数,完成窗口底层初始化。title():设置窗口标题。resizable(False, False):禁止用户拖拽改变窗口大小(宽和高均固定)。
self.celsius = tk.StringVar(value="0")
self.fahrenheit = tk.StringVar(value="32")
- 创建两个
StringVar变量,用于双向绑定输入框的内容。 - 初始值分别为
"0"和"32"(0°C = 32°F),启动时即显示正确对应关系。
self._build_ui()
- 调用私有方法构建界面控件。
self.celsius.trace_add("write", self._from_c)
self.fahrenheit.trace_add("write", self._from_f)
trace_add("write", callback):为变量添加写入监听器。- 当摄氏输入框内容发生变化(用户键入或程序修改)时,自动调用
_from_c更新华氏值。 - 同理,华氏变化时调用
_from_f更新摄氏值。 - 这实现了双向实时同步,无需按钮触发。
3. _build_ui 界面布局
f = ttk.Frame(self, padding=20)
f.pack()
- 创建一个
ttk.Frame作为容器,padding=20提供 20 像素的内边距。 pack()将框架放入主窗口并自动填充。
布局结构(一行网格)
ttk.Label(f, text="°C").grid(row=0, column=1)
ttk.Entry(f, textvariable=self.celsius, width=10).grid(row=0, column=0)
ttk.Label(f, text=" = ").grid(row=0, column=2)
ttk.Entry(f, textvariable=self.fahrenheit, width=10).grid(row=0, column=3)
ttk.Label(f, text="°F").grid(row=0, column=4)
使用 grid() 在同一行(row=0)排布 5 列:
| 列 0 | 列 1 | 列 2 | 列 3 | 列 4 |
|---|---|---|---|---|
| 摄氏输入框 | °C 标签 | = 标签 | 华氏输入框 | °F 标签 |
布局视觉效果:[ 输入框 ] °C = [ 输入框 ] °F
4. 转换回调方法
_from_c — 摄氏 → 华氏
def _from_c(self, *_):
try:
self.fahrenheit.set(f"{float(self.celsius.get())*9/5+32:.2f}")
except:
pass
- 获取摄氏值,转为浮点数,计算华氏:
°F = °C × 9/5 + 32 - 结果保留两位小数(
:.2f)后设置到fahrenheit变量。 - 如果输入为空或非数字,
float()抛出异常,被except静默捕获(无操作)。
_from_f — 华氏 → 摄氏
def _from_f(self, *_):
try:
self.celsius.set(f"{(float(self.fahrenheit.get())-32)*5/9:.2f}")
except:
pass
- 计算摄氏:
°C = (°F - 32) × 5/9 - 同样处理异常情况。
5. 启动应用
TempConverter().mainloop()
- 创建
TempConverter实例并启动 Tkinter 事件循环。 - 窗口显示后,程序持续响应用户输入,直到关闭窗口。
6. 代码亮点总结
| 特性 | 实现方式 |
|---|---|
| 双向实时转换 | StringVar.trace_add("write", callback) 监听变量变化 |
| 异常安全 | 空输入或无效字符时静默忽略,不会崩溃 |
| 界面布局 | 用 grid() 实现简洁的一行布局,Frame 提供内边距 |
| 面向对象 | 继承 tk.Tk,将窗口、变量、UI 构建、逻辑封装于一个类中 |
| 固定窗口大小 | resizable(False, False) 保证布局不变形 |
7. 运行效果
- 窗口标题为 "温度转换器"。
- 两个输入框并排显示,初始为 "0" 和 "32"。
- 在任一输入框中修改数值,另一个输入框会自动同步更新对应的温度值。
- 输入无效内容(如字母或空值)时,另一个输入框保持不变(不更新)。
8. 潜在改进点
- 输入验证:目前无效输入会被忽略,可以添加验证器或错误提示。
- 支持更多温标:可扩展为开尔文、列氏度等。
- 布局灵活性:可改用
grid的sticky或padx调整控件间距。 - 热键支持:可添加键盘快捷键(如 Enter 触发转换)。

浙公网安备 33010602011771号