| 30天学会Python编程:22.Python图形化编程,Tkinter实践指南
					当前位置:点晴教程→知识管理交流
					
					→『 技术文档交流 』
					
				 
 
 | 
# 垂直排列
label1.pack()
label2.pack()
# 水平排列
button1.pack(side=tk.LEFT)
button2.pack(side=tk.LEFT)
# 网格布局
label.grid(row=0, column=0)
entry.grid(row=0, column=1)
button.grid(row=1, column=0, columnspan=2)
# 绝对位置
button.place(x=100, y=50)
# 相对位置
button.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
def on_click():
    print("按钮被点击!")
button = tk.Button(root, text="点击我", command=on_click)
def on_key(event):
    print(f"按键: {event.char}")
root.bind("<Key>", on_key)
<Button-1>:鼠标左键点击<Key>:键盘按键<Motion>:鼠标移动<Configure>:窗口大小变化class Tk(Misc, Wm):
    def __init__(self, screenName=None, baseName=None, className='Tk'):
        ...
功能:创建应用程序主窗口
主要方法:
title(text):设置窗口标题geometry(size):设置窗口大小("宽x高")resizable(width, height):设置窗口是否可调整大小mainloop():启动主事件循环注意事项:
widget.pack(options)  # pack布局
widget.grid(options)  # grid布局
widget.place(options) # place布局
widget.config(**options) # 配置组件属性
widget.bind(sequence, func) # 绑定事件
text_var = tk.StringVar()
entry = tk.Entry(root, textvariable=text_var)
# 获取值
current_text = text_var.get()
# 设置值
text_var.set("新文本")
功能:将组件与变量动态绑定
应用场景:实时同步输入内容、自动更新界面

import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
classStudentManager:
    """学生信息管理系统"""
    
    def__init__(self, root):
        self.root = root
        self.root.title("学生信息管理系统")
        self.root.geometry("800x600")
        self.students = []
        self.data_file = "students.json"
        
        self.load_data()
        self.create_widgets()
    
    defcreate_widgets(self):
        """创建界面组件"""
        
        # 创建菜单栏
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        
        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        file_menu.add_command(label="保存", command=self.save_data)
        file_menu.add_command(label="退出", command=self.root.quit)
        menubar.add_cascade(label="文件", menu=file_menu)
        
        # 工具栏
        toolbar = ttk.Frame(self.root)
        toolbar.pack(fill=tk.X, padx=5, pady=5)
        
        add_btn = ttk.Button(toolbar, text="添加", command=self.add_student)
        add_btn.pack(side=tk.LEFT, padx=2)
        
        del_btn = ttk.Button(toolbar, text="删除", command=self.delete_student)
        del_btn.pack(side=tk.LEFT, padx=2)
        
        # 搜索区域
        search_frame = ttk.Frame(self.root)
        search_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(search_frame, text="搜索:").pack(side=tk.LEFT)
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(search_frame, textvariable=self.search_var)
        search_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        search_entry.bind("<KeyRelease>", self.search_student)
        
        # 学生列表
        list_frame = ttk.Frame(self.root)
        list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        columns = ("id", "name", "score")
        self.tree = ttk.Treeview(
            list_frame, columns=columns, show="headings", selectmode="browse"
        )
        
        # 设置列标题
        self.tree.heading("id", text="学号")
        self.tree.heading("name", text="姓名")
        self.tree.heading("score", text="成绩")
        
        # 设置列宽
        self.tree.column("id", width=100, anchor=tk.CENTER)
        self.tree.column("name", width=200, anchor=tk.W)
        self.tree.column("score", width=100, anchor=tk.CENTER)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.tree.pack(fill=tk.BOTH, expand=True)
        
        # 绑定选择事件
        self.tree.bind("<<TreeviewSelect>>", self.on_select)
        
        # 信息表单
        form_frame = ttk.LabelFrame(self.root, text="学生信息")
        form_frame.pack(fill=tk.X, padx=5, pady=5)
        
        # 学号
        ttk.Label(form_frame, text="学号:").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
        self.id_var = tk.StringVar()
        id_entry = ttk.Entry(form_frame, textvariable=self.id_var)
        id_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W+tk.E)
        
        # 姓名
        ttk.Label(form_frame, text="姓名:").grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
        self.name_var = tk.StringVar()
        name_entry = ttk.Entry(form_frame, textvariable=self.name_var)
        name_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W+tk.E)
        
        # 成绩
        ttk.Label(form_frame, text="成绩:").grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)
        self.score_var = tk.StringVar()
        score_entry = ttk.Entry(form_frame, textvariable=self.score_var)
        score_entry.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W+tk.E)
        
        # 按钮区域
        btn_frame = ttk.Frame(self.root)
        btn_frame.pack(fill=tk.X, padx=5, pady=10)
        
        save_btn = ttk.Button(btn_frame, text="保存", command=self.save_student)
        save_btn.pack(side=tk.RIGHT, padx=5)
        
        clear_btn = ttk.Button(btn_frame, text="清空", command=self.clear_form)
        clear_btn.pack(side=tk.RIGHT, padx=5)
        
        # 加载数据到列表
        self.load_to_treeview()
    
    defload_data(self):
        """从文件加载数据"""
        if os.path.exists(self.data_file):
            try:
                withopen(self.data_file, 'r', encoding='utf-8') as f:
                    self.students = json.load(f)
            except Exception as e:
                messagebox.showerror("错误", f"加载数据失败: {str(e)}")
                self.students = []
    
    defsave_data(self):
        """保存数据到文件"""
        try:
            withopen(self.data_file, 'w', encoding='utf-8') as f:
                json.dump(self.students, f, ensure_ascii=False, indent=2)
            messagebox.showinfo("成功", "数据保存成功!")
        except Exception as e:
            messagebox.showerror("错误", f"保存数据失败: {str(e)}")
    
    defload_to_treeview(self):
        """加载数据到Treeview"""
        # 清空现有数据
        for item inself.tree.get_children():
            self.tree.delete(item)
        
        # 添加新数据
        for student inself.students:
            self.tree.insert("", tk.END, values=(
                student["id"],
                student["name"],
                student["score"]
            ))
    
    defadd_student(self):
        """添加学生"""
        self.clear_form()
        self.id_var.set(self.generate_id())
    
    defgenerate_id(self):
        """生成学号"""
        ifnotself.students:
            return"S001"
        
        max_id = max(int(s["id"][1:]) for s inself.students)
        returnf"S{max_id + 1:03d}"
    
    defsave_student(self):
        """保存学生信息"""
        ifnotself.validate_form():
            return
        
        student = {
            "id": self.id_var.get(),
            "name": self.name_var.get(),
            "score": self.score_var.get()
        }
        
        # 检查是否已存在
        existing_ids = [s["id"] for s inself.students]
        if student["id"] in existing_ids:
            # 更新现有记录
            for i, s inenumerate(self.students):
                if s["id"] == student["id"]:
                    self.students[i] = student
                    break
        else:
            # 添加新记录
            self.students.append(student)
        
        self.load_to_treeview()
        self.clear_form()
        messagebox.showinfo("成功", "学生信息已保存!")
    
    defvalidate_form(self):
        """验证表单数据"""
        ifnotself.id_var.get():
            messagebox.showwarning("警告", "学号不能为空!")
            returnFalse
        
        ifnotself.name_var.get():
            messagebox.showwarning("警告", "姓名不能为空!")
            returnFalse
        
        try:
            float(self.score_var.get())
        except ValueError:
            messagebox.showwarning("警告", "成绩必须是数字!")
            returnFalse
        
        returnTrue
    
    defon_select(self, event):
        """选中学生时加载到表单"""
        selected = self.tree.selection()
        ifnot selected:
            return
        
        item = self.tree.item(selected[0])
        values = item["values"]
        
        self.id_var.set(values[0])
        self.name_var.set(values[1])
        self.score_var.set(values[2])
    
    defdelete_student(self):
        """删除选中学生"""
        selected = self.tree.selection()
        ifnot selected:
            messagebox.showwarning("警告", "请先选择一个学生!")
            return
        
        ifnot messagebox.askyesno("确认", "确定要删除该学生记录吗?"):
            return
        
        item = self.tree.item(selected[0])
        student_id = item["values"][0]
        
        # 从数据中删除
        self.students = [s for s inself.students if s["id"] != student_id]
        
        # 从Treeview删除
        self.tree.delete(selected[0])
        self.clear_form()
    
    defsearch_student(self, event):
        """搜索学生"""
        keyword = self.search_var.get().lower()
        
        # 清空当前显示
        for item inself.tree.get_children():
            self.tree.delete(item)
        
        # 添加匹配项
        for student inself.students:
            if (keyword in student["id"].lower() or
                keyword in student["name"].lower() or
                keyword in student["score"].lower()):
                
                self.tree.insert("", tk.END, values=(
                    student["id"],
                    student["name"],
                    student["score"]
                ))
    
    defclear_form(self):
        """清空表单"""
        self.id_var.set("")
        self.name_var.set("")
        self.score_var.set("")
        self.tree.selection_remove(self.tree.selection())
if __name__ == "__main__":
    root = tk.Tk()
    app = StudentManager(root)
    root.mainloop()
数据管理:
界面特点:
用户体验:
from tkinter import ttk
# 使用ttk主题
style = ttk.Style()
style.theme_use("clam")  # 可选: 'clam', 'alt', 'default', 'classic'
# 自定义样式
style.configure("Custom.TButton", 
                foreground="blue",
                font=("Arial", 12),
                padding=10)
# 应用样式
button = ttk.Button(root, text="美化按钮", style="Custom.TButton")
canvas = tk.Canvas(root, width=400, height=300)
canvas.pack()
# 绘制图形
canvas.create_rectangle(50, 50, 150, 150, fill="blue")
canvas.create_oval(200, 100, 300, 200, fill="red")
canvas.create_line(0, 0, 400, 300, width=2, fill="green")
def open_dialog():
    dialog = tk.Toplevel(root)
    dialog.title("对话框")
    dialog.geometry("300x200")
    tk.Label(dialog, text="这是一个对话框").pack(pady=20)
    ttk.Button(dialog, text="关闭", command=dialog.destroy).pack()
btn = ttk.Button(root, text="打开对话框", command=open_dialog)
btn.pack(pady=20)

代码组织:
错误处理:
用户体验:
性能优化:
深入学习:
项目实践:
进阶方向:
提示:GUI开发的核心不仅是技术实现,更是对用户体验的理解和尊重。好的界面应该让用户感到自然、高效和愉悦。
通过本教程,我们可以掌握Tkinter的核心概念和实践技巧。后续可以通过实际项目不断练习,提升熟练度和解决实际问题的能力!
阅读原文:原文链接