ttk (Themed Tkinter) 是 Python 标准库中 tkinter 的一个扩展模块,提供了更加现代化、主题化的 GUI 组件。与传统的 tkinter 组件相比,ttk 组件具有以下优势:
1 2 |
import tkinter as tk from tkinter import ttk # 导入ttk模块 |
1 2 3 4 5 6 |
# 创建主窗口 root = tk.Tk() # 设置窗口标题 root.title("ttk 教程") # 设置窗口大小(宽x高) root.geometry("400x300") |
1 2 3 4 5 6 7 8 |
# 创建ttk按钮 ttk_button = ttk.Button( root, # 父容器 text="点击我", # 按钮显示文本 command=lambda: print("ttk按钮被点击了") # 点击事件处理函数 ) # 使用pack布局放置按钮 ttk_button.pack(pady=10) # pady设置垂直方向外边距 |
1 2 3 4 5 6 7 |
# 创建ttk标签 ttk_label = ttk.Label( root, # 父容器 text="这是一个ttk标签", # 标签文本 font=("Arial", 12) # 设置字体 ) ttk_label.pack(pady=10) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 创建StringVar用于双向绑定输入框内容 entry_var = tk.StringVar() # 创建ttk输入框 ttk_entry = ttk.Entry( root, # 父容器 textvariable=entry_var, # 绑定变量 width=30 # 设置宽度 ) ttk_entry.pack(pady=10) # 创建显示输入内容的按钮 show_button = ttk.Button( root, text="显示输入内容", command=lambda: print("输入内容:", entry_var.get()) # 获取输入内容 ) show_button.pack(pady=5) |
1 2 3 4 5 6 7 8 9 10 11 |
# 创建ttk组合框 ttk_combobox = ttk.Combobox( root, # 父容器 values=["选项1", "选项2", "选项3"], # 下拉选项 state="readonly" # 设置为只读(不可编辑) ) ttk_combobox.pack(pady=10) ttk_combobox.set("请选择") # 设置默认显示文本 # 绑定选择事件 ttk_combobox.bind("<<ComboboxSelected>>", lambda e: print("选择了:", ttk_combobox.get())) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 创建进度条变量 progress_var = tk.DoubleVar() # 创建ttk进度条 progress = ttk.Progressbar( root, # 父容器 variable=progress_var, # 绑定变量 maximum=100, # 最大值 length=200 # 进度条长度 ) progress.pack(pady=10) # 创建控制进度条的按钮 start_button = ttk.Button( root, text="开始进度", command=lambda: progress.start(10) # 以10ms间隔开始自动增加 ) start_button.pack(side=tk.LEFT, padx=5) stop_button = ttk.Button( root, text="停止进度", command=progress.stop # 停止自动增加 ) stop_button.pack(side=tk.LEFT, padx=5) |
1 2 3 4 5 6 7 8 9 10 11 |
# 创建ttk笔记本(标签页容器) notebook = ttk.Notebook(root) notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 填充整个空间 # 创建第一个标签页 frame1 = ttk.Frame(notebook) ttk.Label(frame1, text="这是标签页1的内容").pack(pady=20) notebook.add(frame1, text="标签页1") # 添加标签页 # 创建第二个标签页 frame2 = ttk.Frame(notebook) ttk.Label(frame2, text="这是标签页2的内容").pack(pady=20) notebook.add(frame2, text="标签页2") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 创建ttk树视图 tree = ttk.Treeview(root, columns=("name", "age"), show="headings") # 设置列标题 tree.heading("name", text="姓名") tree.heading("age", text="年龄") # 设置列宽度 tree.column("name", width=100) tree.column("age", width=50) # 插入数据 tree.insert("", tk.END, values=("张三", 25)) tree.insert("", tk.END, values=("李四", 30)) tree.insert("", tk.END, values=("王五", 28)) tree.pack(pady=10) # 绑定选中事件 tree.bind("<<TreeviewSelect>>", lambda e: print("选中了:", tree.item(tree.focus())["values"])) |
ttk 允许自定义组件样式,使其更符合应用需求。
1 2 3 4 5 6 |
# 获取默认样式对象 style = ttk.Style() # 查看当前可用主题 print("可用主题:", style.theme_names()) # 设置主题 style.theme_use("clam") # 使用clam主题 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 配置TButton样式(所有按钮) style.configure( "TButton", # 样式名称 foreground="blue", # 前景色(文字颜色) font=("Arial", 12, "bold"), # 字体 padding=10 # 内边距 ) # 创建自定义样式的按钮 custom_button = ttk.Button( root, text="自定义样式按钮", style="TButton" # 应用样式 ) custom_button.pack(pady=10) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 定义新样式 Danger.TButton style.configure( "Danger.TButton", # 新样式名 foreground="red", # 红色文字 font=("Arial", 12, "bold") ) # 使用新样式的按钮 danger_button = ttk.Button( root, text="危险操作", style="Danger.TButton" # 应用新样式 ) danger_button.pack(pady=10) |
下面是一个结合了多个ttk组件的完整示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import tkinter as tk from tkinter import ttk from tkinter import messagebox class TtkDemoApp: def __init__(self, root): self.root = root self.root.title("ttk 综合示例") self.root.geometry("500x500") # 创建样式 self.setup_styles() # 创建界面 self.create_widgets() def setup_styles(self): """设置自定义样式""" self.style = ttk.Style() self.style.theme_use("clam") # 配置默认按钮样式 self.style.configure( "TButton", padding=6, font=("Arial", 10) ) # 创建成功按钮样式 self.style.configure( "Success.TButton", foreground="green", font=("Arial", 10, "bold") ) def create_widgets(self): """创建所有界面组件""" # 创建笔记本(标签页) self.notebook = ttk.Notebook(self.root) self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 创建第一个标签页 - 表单 self.create_form_tab() # 创建第二个标签页 - 数据展示 self.create_data_tab() def create_form_tab(self): """创建表单标签页""" form_frame = ttk.Frame(self.notebook) self.notebook.add(form_frame, text="表单") # 表单标题 ttk.Label( form_frame, text="用户注册表单", font=("Arial", 14, "bold") ).pack(pady=10) # 用户名输入 ttk.Label(form_frame, text="用户名:").pack() self.username = ttk.Entry(form_frame, width=30) self.username.pack(pady=5) # 密码输入 ttk.Label(form_frame, text="密码:").pack() self.password = ttk.Entry(form_frame, width=30, show="*") self.password.pack(pady=5) # 性别选择 ttk.Label(form_frame, text="性别:").pack() self.gender = tk.StringVar() ttk.Radiobutton(form_frame, text="男", variable=self.gender, value="male").pack() ttk.Radiobutton(form_frame, text="女", variable=self.gender, value="female").pack() # 兴趣爱好 ttk.Label(form_frame, text="兴趣爱好:").pack() self.hobbies = { "reading": tk.BooleanVar(), "sports": tk.BooleanVar(), "music": tk.BooleanVar() } ttk.Checkbutton(form_frame, text="阅读", variable=self.hobbies["reading"]).pack() ttk.Checkbutton(form_frame, text="运动", variable=self.hobbies["sports"]).pack() ttk.Checkbutton(form_frame, text="音乐", variable=self.hobbies["music"]).pack() # 提交按钮 ttk.Button( form_frame, text="提交", style="Success.TButton", command=self.submit_form ).pack(pady=20) def create_data_tab(self): """创建数据展示标签页""" data_frame = ttk.Frame(self.notebook) self.notebook.add(data_frame, text="数据") # 树视图 self.tree = ttk.Treeview( data_frame, columns=("name", "age", "department"), show="headings" ) # 设置列 self.tree.heading("name", text="姓名") self.tree.heading("age", text="年龄") self.tree.heading("department", text="部门") # 设置列宽 self.tree.column("name", width=100) self.tree.column("age", width=50) self.tree.column("department", width=150) self.tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 添加一些示例数据 self.add_sample_data() # 添加控制按钮 control_frame = ttk.Frame(data_frame) control_frame.pack(pady=5) ttk.Button( control_frame, text="添加数据", command=self.add_data ).pack(side=tk.LEFT, padx=5) ttk.Button( control_frame, text="删除选中", command=self.delete_selected ).pack(side=tk.LEFT, padx=5) def add_sample_data(self): """添加示例数据到树视图""" sample_data = [ ("张三", 28, "技术部"), ("李四", 32, "市场部"), ("王五", 25, "人事部") ] for data in sample_data: self.tree.insert("", tk.END, values=data) def add_data(self): """添加新数据""" self.tree.insert("", tk.END, values=("新员工", 0, "未分配")) def delete_selected(self): """删除选中行""" selected_item = self.tree.selection() if selected_item: self.tree.delete(selected_item) else: messagebox.showwarning("警告", "请先选择要删除的行") def submit_form(self): """处理表单提交""" username = self.username.get() password = self.password.get() gender = self.gender.get() hobbies = [hobby for hobby, var in self.hobbies.items() if var.get()] if not username or not password: messagebox.showerror("错误", "用户名和密码不能为空") return message = f""" 注册信息: 用户名: {username} 性别: {gender if gender else '未选择'} 兴趣爱好: {', '.join(hobbies) if hobbies else '无'} """ messagebox.showinfo("注册成功", message) self.username.delete(0, tk.END) self.password.delete(0, tk.END) self.gender.set("") for var in self.hobbies.values(): var.set(False) if __name__ == "__main__": root = tk.Tk() app = TtkDemoApp(root) root.mainloop() |
ttk 模块为 Python 的 GUI 开发提供了更加现代化和灵活的组件,主要特点包括:
通过本教程,你应该已经掌握了 ttk 的基本使用方法,包括常用组件的创建、布局、事件绑定以及样式定制。ttk 与传统的 tkinter 组件可以混合使用,但为了保持界面一致性,建议尽可能使用 ttk 组件。
在实际开发中,你可以根据需求选择合适的组件,并通过样式系统来创建符合品牌或设计要求的界面。