环境
- Python版本:3.8
- ttkbootstrap版本:1.11.0
代码
# !/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Creator: Wang
Date: 2025/8/1
Description: 基于tk的ttkbootstrap框架桌面开发示例代码
"""
import time
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.dialogs import Messagebox
from tkinter import filedialog# 按钮1点击事件
def btn1_click():Messagebox.show_info(str(chk_var.get())+ "," + str(rao_var.get())+ "," + str(comb_var.get())+ "," + str(date_obj.entry.get())+ "," + str(entry_var.get()), "来自ttk提示", position=CENTER)# 按钮2点击事件
def btn2_click():for i in range(101):fldg_obj.configure(value=i) # 动态修改组件,用configureroot.update()time.sleep(0.01)Messagebox.show_info("完成!")# 按钮3点击事件
def btn3_click():for i in range(101):meter_obj.configure(amountused=i) # 动态修改组件,用configureif i == 100: meter_obj.configure(subtext="处理完成")root.update()time.sleep(0.01)Messagebox.show_info("完成!")# 按钮4点击事件
def btn4_click():for i in range(101):pb_obj.configure(value=i) # 动态修改组件,用configurepb_label_obj.config(text=f"当前进度:{i}%")root.update()time.sleep(0.01)Messagebox.show_info("完成!")# 浏览文件按钮点击事件
def file_btn_click():path = filedialog.askopenfilename(title="选择Excel文件", filetypes=[("Excel文件", "*.xls"), ("Excel文件", "*.xlsx")])if path:file_entry_var.set(path)file_entry_obj.focus_set()file_entry_obj.icursor("end")# 菜单-文件-打开
def open_file():Messagebox.show_info("打开文件")# 菜单-文件-另存
def save_other_file():Messagebox.show_info("另存文件")# 菜单-帮助-关于
def show_about():Messagebox.show_info("Demo演示系统v1.0\n开发者:Wong\n\n©版权所有 2025")# 创建一个窗口
# title:窗口标题; size:窗口大小
# root.update():刷新界面元素,此方法也可防止界面阻塞
root = ttk.Window(title="ttk演示系统", size=(1600, 1200))# Checkbutton,Radiobutton,Combobox表单元素绑定值之前,先声明变量/类型
# value:默认赋值
# 以下变量声明必须在ttk.Window()初始化之后!
chk_var = ttk.BooleanVar(value=TRUE)
rao_var = ttk.StringVar(value="0")
comb_var = ttk.StringVar(value="")
date_var = ttk.StringVar(value="")
entry_var = ttk.StringVar(value="")
# fldg_var = ttk.StringVar(value="")
# meter_var = ttk.StringVar(value="")
file_entry_var = ttk.StringVar(value="")# 按钮-Button
# text:按钮文本; bootstyle:显示样式,支持元组多个值; command:监听事件函数
# grid():表格布局类型; row:第几行; column:第几列; padx:水平间隔; pady:垂直间隔; sticky:布局中对齐方式(W西 E东)
# pack():自动布局类型, anchor=NW:靠左上角, fill=X:水平填充, side=LEFT:左浮动之意
ttk.Button(root, text="按钮1 提示框", bootstyle=SUCCESS, command=btn1_click).grid(row=1, column=1, padx=10, pady=15, sticky=W)
ttk.Button(root, text="按钮2 洪水进度条", bootstyle=PRIMARY, command=btn2_click).grid(row=1, column=2, padx=10, pady=15, sticky=W)
ttk.Button(root, text="按钮3 环形进度", bootstyle=DANGER, command=btn3_click).grid(row=1, column=3, padx=10, pady=15, sticky=W)
ttk.Button(root, text="按钮4 普通进度条", bootstyle=INFO, command=btn4_click).grid(row=1, column=4, padx=10, pady=15, sticky=W)# 复选框-Checkbutton
# variable:动态绑定变量
ttk.Checkbutton(root, text="选择", bootstyle=(ROUND, TOGGLE), variable=chk_var).grid(row=2, column=1, padx=10, pady=15, sticky=W)# 单选按钮-Radiobutton
# variable:动态绑定变量
ttk.Radiobutton(root, text="精确", value="1", variable=rao_var).grid(row=2, column=2, padx=10, pady=15, sticky=W)
ttk.Radiobutton(root, text="模糊", value="0", variable=rao_var).grid(row=2, column=3, padx=10, pady=15, sticky=W)# 文本标签-Label
ttk.Label(root, text="选择一项:").grid(row=3, column=1, padx=10, pady=15, sticky=W)# 下拉组合框-Combobox
# textvariable:动态绑定文本变量,注意不是variable; columnspan:独占列数
ttk.Combobox(root, values=["Python", "Java", "C++", "Go", "PHP"], textvariable=comb_var, state="readonly").grid(row=3, column=2, columnspan=2, pady=15, sticky=W)# 日期-DateEntry
# width:宽度; dateformat:日期格式化
# **特别提醒**:当组件链式调用布局管理方法(grid/pack/place),得到的是布局管理返回值,而非组件对象,如需得到组件对象,需要将组件创建和布局管理分开操作(其它组件亦然)
# 取值方法:date_obj.entry.get()
date_obj = ttk.DateEntry(root, width=15, dateformat=r"%Y-%m-%d")
date_obj.grid(row=3, column=4, columnspan=2, padx=10, pady=15, sticky=W)# 输入框-Entry
# textvariable:动态绑定文本变量,注意不是variable
ttk.Entry(root, width=20, textvariable=entry_var).grid(row=3, column=6, columnspan=2, padx=10, pady=15, sticky=W)# 洪水进度条-Floodgauge
# length:显示长度(宽度); value:当前值; maximum:最大值; textvariable:动态绑定文本变量; mask:进度条上显示的文本模板({}会被替换为当前进度值)
fldg_obj = ttk.Floodgauge(root, mask="当前进度 {}%", length=500, value=0, maximum=100, bootstyle=SUCCESS)
fldg_obj.grid(row=4, column=1, columnspan=4, padx=10, pady=15, sticky=W)# 菜单栏-Menu
# tearoff=0:菜单固定,不可浮动
menu_bar = ttk.Menu(root) # 先创建菜单条
file_menu = ttk.Menu(menu_bar, tearoff=0) # [文件]菜单
file_menu.add_command(label="打开", command=open_file)
file_menu.add_command(label="另存", command=save_other_file)
file_menu.add_separator() # 分割线
file_menu.add_command(label="退出", command=root.quit)
menu_bar.add_cascade(label="文件", menu=file_menu) # 菜单条添加[文件]菜单help_menu = ttk.Menu(menu_bar, tearoff=0) # [帮助]菜单
help_menu.add_command(label="关于", command=show_about)
menu_bar.add_cascade(label="帮助", menu=help_menu) # 菜单条添加[帮助]菜单
# 主窗口添加菜单条
root.config(menu=menu_bar)# 环形进度条-Meter
# metersize:显示大小; amountused:当前进度; amounttotal:最大值; meterthickness:进度条厚度; stripethickness:条纹厚度(用于分段效果); textvariable:动态绑定文本变量
meter_obj = ttk.Meter(root, metersize=150, amountused=0, amounttotal=100, meterthickness=10, stripethickness=10, textleft="进度", textright="%", subtext="正在处理中...")
meter_obj.grid(row=5, column=1, columnspan=4, padx=10, pady=15, sticky=W)# 标签页-Notebook
# width:宽度; height:高度
notebook_obj = ttk.Notebook(root, bootstyle="info", width=800, height=100) # 初始化Notebook组件
notebook_obj.grid(row=6, column=1, columnspan=10, padx=10, pady=15, sticky=W)
tab1 = ttk.Frame(notebook_obj) # 第一个标签
notebook_obj.add(tab1, text="基本信息区") # 在Notebook中添加标签页
ttk.Label(tab1, text="基本信息区中的内容").grid(row=1, column=1, columnspan=1, padx=10, pady=15)
tab2 = ttk.Frame(notebook_obj) # 第二个标签
notebook_obj.add(tab2, text="系统设置区") # 在Notebook中添加标签页
ttk.Label(tab2, text="系统设置区中的内容").grid(row=1, column=1, columnspan=1, padx=10, pady=15)# 普通进度条-Progressbar
pb_obj = ttk.Progressbar(root, length=300, value=30, maximum=100, bootstyle=STRIPED)
pb_obj.grid(row=7, column=1, columnspan=2, padx=10, pady=15, sticky=W)
pb_label_obj = ttk.Label(root, text="当前进度:30%")
pb_label_obj.grid(row=7, column=3, padx=10, pady=15, sticky=W)# 滑动条-Scale
# from_:起始值; to:终点值
scale_obj = ttk.Scale(root, length=300, from_=0, to=100, value=50, bootstyle="warning")
scale_obj.grid(row=7, column=4, columnspan=2, padx=10, pady=15, sticky=W)# 分割线-Separator
# grid布局时,通过columnspan和sticky=EW控制长度
# pack布局时,通过fill=X控制长度
ttk.Label(root, text="分割线").grid(row=8, column=1, columnspan=1, padx=10, pady=15, sticky=W)
ttk.Separator(root).grid(row=8, column=2, columnspan=6, padx=10, pady=15, sticky=EW)# 文件对话框-采用 tkinter 的 filedialog.askopenfilename() 方法
# state=READONLY:输入框只读
ttk.Label(root, text="选择Excel文件").grid(row=9, column=1, columnspan=1, padx=10, pady=15, sticky=W)
file_entry_obj = ttk.Entry(root, width=40, textvariable=file_entry_var)
file_entry_obj.grid(row=9, column=2, columnspan=2, padx=10, pady=15, sticky=W)
ttk.Button(root, text="浏览", bootstyle=PRIMARY, command=file_btn_click).grid(row=9, column=4, padx=10, pady=15, sticky=W)# 模拟无限循环进度条
def infinite_progress():current = pb_loop_obj["value"] # 取进度条的值if current < 100:# 动态调整样式if current < 30:pb_loop_obj.configure(bootstyle=(STRIPED, DANGER))elif 30 <= current < 70:pb_loop_obj.configure(bootstyle=(STRIPED, WARNING))else:pb_loop_obj.configure(bootstyle=(STRIPED, SUCCESS))pb_loop_obj["value"] = current + 1else:pb_loop_obj["value"] = 0 # 重置进度条global after_idafter_id = root.after(30, infinite_progress) # x ms后继续执行,after()返回after_id,方便将来根据它结束after# 根据after_id结束after
def stop_progress(after_id):root.after_cancel(after_id)pb_loop_obj["value"] = 0pb_loop_obj = ttk.Progressbar(root, length=300, value=0, maximum=100, bootstyle=STRIPED)
pb_loop_obj.grid(row=10, column=1, columnspan=2, padx=10, pady=15, sticky=W)
ttk.Button(root, text="启动进度条", bootstyle=SUCCESS, command=infinite_progress).grid(row=10, column=3, padx=10, pady=15, sticky=W)
ttk.Button(root, text="结束进度条", bootstyle=PRIMARY, command=lambda: stop_progress(after_id)).grid(row=10, column=4, padx=10, pady=15, sticky=W)# 滚动条文本域-ScrolledText
# height:高度; width:宽度; 起始位置为1.0(首行首字符),结束位置为END
# 文本插入:text_obj.insert(END, "插入的文本内容"); 文本获取:text_obj.get("1.0", END); 文本清空:text_obj.delete("1.0", END); 自动滚动至底部:text_obj.see(END)
ttk.Label(root, text="日志输出:").grid(row=11, column=1, padx=10, pady=15, sticky=W)
text_obj = ttk.ScrolledText(root, height=4, width=100)
text_obj.grid(row=12, column=1, columnspan=10, padx=10, pady=15, sticky=W)# 渲染界面
root.place_window_center() # 使窗口屏幕居中
root.mainloop()
效果
