当前位置: 首页 > news >正文

Python--Tkinter--标准 GUI 工具包

Tkinter 自学指南与完整案例 (纯deepseek版-自用)

Tkinter 是 Python 的标准 GUI 工具包,用于创建桌面应用程序。下面是一个完整的学习指南和案例,包含从基础到高级的应用。

基础框架

import tkinter as tk
from tkinter import ttk, messageboxclass App(tk.Tk):def __init__(self):super().__init__()self.title("Tkinter 学习应用")self.geometry("800x600")self.create_widgets()def create_widgets(self):# 创建标签self.label = ttk.Label(self, text="欢迎使用 Tkinter!", font=("Arial", 16))self.label.pack(pady=20)# 创建按钮self.button = ttk.Button(self, text="点击我", command=self.on_button_click)self.button.pack(pady=10)# 创建输入框self.entry = ttk.Entry(self, width=30)self.entry.pack(pady=10)self.entry.insert(0, "在这里输入文本")# 创建文本框self.text = tk.Text(self, height=10, width=50)self.text.pack(pady=10, padx=20, fill=tk.BOTH, expand=True)self.text.insert("1.0", "这是一个多行文本框...\n")# 创建下拉框self.combo = ttk.Combobox(self, values=["选项1", "选项2", "选项3"])self.combo.pack(pady=10)self.combo.current(0)# 创建复选框self.check_var = tk.BooleanVar()self.check = ttk.Checkbutton(self, text="启用功能", variable=self.check_var)self.check.pack(pady=10)# 创建单选按钮self.radio_var = tk.StringVar(value="A")self.radio1 = ttk.Radiobutton(self, text="选项 A", variable=self.radio_var, value="A")self.radio2 = ttk.Radiobutton(self, text="选项 B", variable=self.radio_var, value="B")self.radio1.pack()self.radio2.pack()def on_button_click(self):entry_text = self.entry.get()combo_value = self.combo.get()check_state = self.check_var.get()radio_value = self.radio_var.get()self.text.insert("end", f"\n按钮被点击!\n输入内容: {entry_text}")self.text.insert("end", f"\n下拉框: {combo_value}, 复选框: {check_state}, 单选按钮: {radio_value}")messagebox.showinfo("信息", f"你选择了: {combo_value}")if __name__ == "__main__":app = App()app.mainloop()

完整案例:待办事项应用

import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
from datetime import datetimeclass TodoApp(tk.Tk):def __init__(self):super().__init__()self.title("待办事项管理器")self.geometry("800x600")self.tasks = []self.load_tasks()self.create_widgets()def load_tasks(self):"""从文件加载任务"""if os.path.exists("tasks.json"):try:with open("tasks.json", "r") as f:self.tasks = json.load(f)except:self.tasks = []def save_tasks(self):"""保存任务到文件"""with open("tasks.json", "w") as f:json.dump(self.tasks, f)def create_widgets(self):"""创建界面组件"""# 创建主框架main_frame = ttk.Frame(self)main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)# 输入区域input_frame = ttk.LabelFrame(main_frame, text="添加新任务")input_frame.pack(fill=tk.X, pady=(0, 10))ttk.Label(input_frame, text="任务内容:").grid(row=0, column=0, padx=5, pady=5, sticky="w")self.task_entry = ttk.Entry(input_frame, width=40)self.task_entry.grid(row=0, column=1, padx=5, pady=5, sticky="ew")ttk.Label(input_frame, text="优先级:").grid(row=0, column=2, padx=5, pady=5, sticky="w")self.priority_var = tk.StringVar(value="中")priority_combo = ttk.Combobox(input_frame, textvariable=self.priority_var, values=["低", "中", "高"], state="readonly", width=8)priority_combo.grid(row=0, column=3, padx=5, pady=5)ttk.Label(input_frame, text="截止日期:").grid(row=0, column=4, padx=5, pady=5, sticky="w")self.due_date_entry = ttk.Entry(input_frame, width=12)self.due_date_entry.grid(row=0, column=5, padx=5, pady=5)self.due_date_entry.insert(0, datetime.now().strftime("%Y-%m-%d"))add_btn = ttk.Button(input_frame, text="添加任务", command=self.add_task)add_btn.grid(row=0, column=6, padx=5, pady=5)# 任务列表list_frame = ttk.LabelFrame(main_frame, text="任务列表")list_frame.pack(fill=tk.BOTH, expand=True, pady=10)columns = ("id", "task", "priority", "due_date", "completed")self.tree = ttk.Treeview(list_frame, columns=columns, show="headings", selectmode="browse")# 设置列宽和标题self.tree.column("id", width=50, anchor="center")self.tree.column("task", width=300, anchor="w")self.tree.column("priority", width=80, anchor="center")self.tree.column("due_date", width=100, anchor="center")self.tree.column("completed", width=80, anchor="center")self.tree.heading("id", text="ID")self.tree.heading("task", text="任务内容")self.tree.heading("priority", text="优先级")self.tree.heading("due_date", text="截止日期")self.tree.heading("completed", text="完成状态")# 添加滚动条scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.tree.yview)self.tree.configure(yscrollcommand=scrollbar.set)self.tree.pack(side="left", fill=tk.BOTH, expand=True)scrollbar.pack(side="right", fill="y")# 操作按钮btn_frame = ttk.Frame(main_frame)btn_frame.pack(fill=tk.X, pady=10)complete_btn = ttk.Button(btn_frame, text="标记完成", command=self.mark_completed)complete_btn.pack(side="left", padx=5)edit_btn = ttk.Button(btn_frame, text="编辑任务", command=self.edit_task)edit_btn.pack(side="left", padx=5)delete_btn = ttk.Button(btn_frame, text="删除任务", command=self.delete_task)delete_btn.pack(side="left", padx=5)# 状态栏self.status_var = tk.StringVar(value="就绪")status_bar = ttk.Label(self, textvariable=self.status_var, relief="sunken", anchor="w")status_bar.pack(side="bottom", fill=tk.X)# 填充任务列表self.refresh_task_list()def refresh_task_list(self):"""刷新任务列表"""# 清空现有列表for item in self.tree.get_children():self.tree.delete(item)# 添加任务到列表for idx, task in enumerate(self.tasks, 1):completed = "是" if task.get("completed", False) else "否"priority = task.get("priority", "中")# 根据优先级设置标签tags = ()if priority == "高":tags = ("high",)elif priority == "低":tags = ("low",)self.tree.insert("", "end", values=(idx,task["task"],priority,task.get("due_date", ""),completed), tags=tags)# 配置标签样式self.tree.tag_configure("high", background="#ffcccc")  # 高优先级红色背景self.tree.tag_configure("low", background="#ccffcc")   # 低优先级绿色背景def add_task(self):"""添加新任务"""task_text = self.task_entry.get().strip()if not task_text:messagebox.showerror("错误", "任务内容不能为空")returndue_date = self.due_date_entry.get().strip()priority = self.priority_var.get()new_task = {"task": task_text,"due_date": due_date,"priority": priority,"completed": False,"created_at": datetime.now().strftime("%Y-%m-%d %H:%M")}self.tasks.append(new_task)self.save_tasks()self.refresh_task_list()self.task_entry.delete(0, "end")self.status_var.set(f"任务 '{task_text}' 已添加")def get_selected_task(self):"""获取选中的任务"""selected = self.tree.selection()if not selected:messagebox.showinfo("提示", "请先选择一个任务")return Noneitem = self.tree.item(selected[0])idx = item["values"][0] - 1  # 从1开始的索引转列表索引if 0 <= idx < len(self.tasks):return idx, self.tasks[idx]return Nonedef mark_completed(self):"""标记任务为完成"""task_info = self.get_selected_task()if task_info is None:returnidx, task = task_infotask["completed"] = not task["completed"]self.save_tasks()self.refresh_task_list()status = "完成" if task["completed"] else "未完成"self.status_var.set(f"任务 '{task['task']}' 标记为 {status}")def edit_task(self):"""编辑任务"""task_info = self.get_selected_task()if task_info is None:returnidx, task = task_info# 创建编辑窗口edit_win = tk.Toplevel(self)edit_win.title("编辑任务")edit_win.geometry("400x300")edit_win.transient(self)edit_win.grab_set()ttk.Label(edit_win, text="任务内容:").pack(pady=(10, 5), padx=10, anchor="w")task_entry = ttk.Entry(edit_win, width=40)task_entry.pack(fill=tk.X, padx=10, pady=5)task_entry.insert(0, task["task"])ttk.Label(edit_win, text="优先级:").pack(pady=5, padx=10, anchor="w")priority_var = tk.StringVar(value=task.get("priority", "中"))priority_combo = ttk.Combobox(edit_win, textvariable=priority_var, values=["低", "中", "高"], state="readonly", width=8)priority_combo.pack(anchor="w", padx=10, pady=5)ttk.Label(edit_win, text="截止日期:").pack(pady=5, padx=10, anchor="w")due_date_entry = ttk.Entry(edit_win, width=12)due_date_entry.pack(anchor="w", padx=10, pady=5)due_date_entry.insert(0, task.get("due_date", ""))completed_var = tk.BooleanVar(value=task.get("completed", False))completed_check = ttk.Checkbutton(edit_win, text="已完成", variable=completed_var)completed_check.pack(anchor="w", padx=10, pady=10)def save_changes():task["task"] = task_entry.get().strip()task["priority"] = priority_var.get()task["due_date"] = due_date_entry.get().strip()task["completed"] = completed_var.get()self.save_tasks()self.refresh_task_list()edit_win.destroy()self.status_var.set(f"任务 '{task['task']}' 已更新")save_btn = ttk.Button(edit_win, text="保存", command=save_changes)save_btn.pack(pady=10)def delete_task(self):"""删除任务"""task_info = self.get_selected_task()if task_info is None:returnidx, task = task_infoif messagebox.askyesno("确认", f"确定要删除任务 '{task['task']}' 吗?"):del self.tasks[idx]self.save_tasks()self.refresh_task_list()self.status_var.set(f"任务 '{task['task']}' 已删除")if __name__ == "__main__":app = TodoApp()app.mainloop()

Tkinter 学习要点

1. 核心组件

组件类名描述
窗口tk.Tk主应用程序窗口
标签ttk.Label显示文本或图像
按钮ttk.Button可点击按钮
输入框ttk.Entry单行文本输入
文本框tk.Text多行文本输入/显示
下拉框ttk.Combobox下拉选择框
复选框ttk.Checkbutton多选项选择
单选按钮ttk.Radiobutton单选项选择
列表框tk.Listbox项目列表显示
树状视图ttk.Treeview表格或树形数据展示
滚动条ttk.Scrollbar滚动支持

2. 布局管理

布局管理器描述示例
pack()简单自动布局widget.pack(side="left", fill="y")
grid()网格布局widget.grid(row=0, column=0, sticky="nsew")
place()精确位置布局widget.place(x=10, y=20, width=100, height=50)

3. 事件处理

# 按钮点击事件
button = ttk.Button(root, text="Click", command=on_click)# 键盘事件
entry = ttk.Entry(root)
entry.bind("<Return>", on_enter_pressed)# 鼠标事件
canvas = tk.Canvas(root)
canvas.bind("<Button-1>", on_left_click)
canvas.bind("<Motion>", on_mouse_move)# 窗口事件
root.protocol("WM_DELETE_WINDOW", on_window_close)

4. 对话框

from tkinter import messagebox, filedialog# 消息对话框
messagebox.showinfo("标题", "信息内容")
messagebox.showwarning("警告", "警告内容")
messagebox.showerror("错误", "错误内容")
answer = messagebox.askyesno("确认", "确定吗?")# 文件对话框
file_path = filedialog.askopenfilename(title="选择文件")
dir_path = filedialog.askdirectory(title="选择文件夹")
save_path = filedialog.asksaveasfilename(title="保存文件")

5. 样式与主题

# 创建样式对象
style = ttk.Style()# 查看可用主题
print(style.theme_names())# 设置主题
style.theme_use("clam")# 自定义样式
style.configure("TButton", padding=6, font=("Arial", 10))
style.map("TButton", foreground=[("pressed", "red"), ("active", "blue")],background=[("pressed", "!disabled", "black"), ("active", "white")])

学习资源

  1. 官方文档

    • Tkinter 文档
    • Ttk 文档
  2. 教程推荐

    • Real Python: Python GUI With Tkinter
    • TkDocs 教程
  3. 扩展库

    • customtkinter:现代化主题的 Tkinter
    • tkcalendar:日期选择组件
    • PIL (Pillow):图像处理支持
  4. 项目实践

    • 计算器应用
    • 文本编辑器
    • 数据可视化工具
    • 简单的游戏(如贪吃蛇)

总结

Tkinter 是 Python GUI 开发的入门首选:

  • 优点:内置标准库、跨平台、简单易学
  • 缺点:界面较传统、高级功能有限
  • 适用场景:小型工具、教学示例、快速原型开发

通过本文提供的待办事项应用案例,您可以掌握:

  1. 创建主窗口和组件
  2. 使用多种布局管理器
  3. 处理用户交互事件
  4. 实现数据持久化(JSON)
  5. 创建对话框和子窗口
  6. 使用 Treeview 展示表格数据
  7. 应用样式和主题

继续学习时,建议:

  1. 从简单组件开始,逐步组合复杂界面
  2. 多参考官方文档和示例代码
  3. 尝试重写本文案例,添加新功能
  4. 探索更多 Tkinter 组件和扩展库
http://www.lryc.cn/news/597530.html

相关文章:

  • STL学习(?函数对象,谓词,内建函数对象)
  • Hexo - 免费搭建个人博客05 - 更新个人博客
  • DAY 22 复习日
  • 【提示词技巧】高级提示方法与框架
  • 第七章 Pytorch构建模型详解【构建CIFAR10模型结构】
  • 【WRF】根据自动安装脚本安装 WRF / WRF-CHEM等
  • Google Chrome V8< 14.0.221 类型混淆漏洞
  • linux中如何清除history命令
  • IAR Embedded Workbench for ARM 8.1 安装教程
  • 有没有能读懂PDF里手写批注的工具?
  • C# 值类型与引用类型的储存方式_堆栈_
  • 基于Kafka实现简单的延时队列
  • 【JVM】从 JVM 整体说明 JVM 运行的完整流程
  • C#与WPF使用mvvm简单案例点击按钮触发弹窗
  • 基于阿里云平台的文章评价模型训练与应用全流程指南
  • nginx.conf配置文件以及指令详解
  • 人工智慧是引擎,人类是方向盘:Vitalik对AI未来的深刻反思
  • 关于SPring基础和Vue的学习
  • rust嵌入式开发零基础入门教程(六)
  • 什么是MySQL 视图
  • 综合实验(3)
  • 暑期自学嵌入式——Day06(C语言阶段)
  • 7月23日星期三今日早报简报微语报早读
  • 51c大模型~合集158
  • Vue 3 组件通信全解析:从 Props 到 Pinia 的深入实践
  • 用 llama.cpp 构建高性能本地 AI 应用:从环境搭建到多工具智能体开发全流程实战
  • Python应用指南:构建和获取全球地铁线路数据及可视化
  • ToBToC的定义与区别
  • 从 XSS 到 Bot 攻击:常见网络攻击防不胜防?雷池 WAF 用全场景防护为网站筑牢安全墙
  • Java中IO多路复用技术详解