Tkinter教程28:ttk.Style()有哪些内置的主题样式?

ttk.Style()有哪些主题样式,我记得不同的操作系统可能有不同的内置主题。比如在Windows上可能有’winnative’, ‘clam’, ‘alt’, ‘classic’, ‘vista’, ‘xpnative’之类的,而Linux下的主题可能有’clam’, ‘alt’, ‘default’, ‘classic’,而macOS可能有’aqua’或者其他名称。不过具体的可用主题可能因系统和Tk版本而异,所以最好是通过代码先获取当前可用的主题列表。

测试这些主题样式在多个组件上的效果。组件的话,常见的ttk组件包括Button、Label、Entry、Checkbutton、Radiobutton、Combobox、Frame、Notebook、Progressbar、Treeview等。需要创建一个示例窗口,展示这些组件在不同主题下的外观变化。

当前主题是: clam
在这里插入图片描述

# -*- coding: utf-8 -*-
# @Author : 小红牛
# 微信公众号:WdPython
import tkinter as tk
from tkinter import ttk

def create_demo_widgets(parent):
    """创建一组ttk组件用于演示主题效果"""
    frame = ttk.Frame(parent, padding=10)
    frame.pack(padx=10, pady=10, fill='both', expand=True)

    # 标签
    ttk.Label(frame, text='这是一个标签:').grid(row=0, column=0, sticky='w')
    # 输入框
    ttk.Entry(frame, width=15).grid(row=0, column=1, padx=5)
    # 按钮
    ttk.Button(frame, text='按钮', command=lambda: print("点击按钮")).grid(row=0, column=2, padx=5)
    # 复选框
    ttk.Checkbutton(frame, text='复选框').grid(row=1, column=0, sticky='w', pady=5)
    # 单选框
    radio_var = tk.StringVar()
    ttk.Radiobutton(frame, text='选项1', variable=radio_var, value='1').grid(row=2, column=0, sticky='w')
    ttk.Radiobutton(frame, text='选项2', variable=radio_var, value='2').grid(row=3, column=0, sticky='w')
    # 下拉框
    combo = ttk.Combobox(frame, values=["选项1", "选项2", "选项3"], state='readonly')
    combo.current(0)
    combo.grid(row=1, column=1, pady=5)
    # 进度条
    progress = ttk.Progressbar(frame, orient='horizontal', length=100, mode='determinate')
    progress.grid(row=1, column=2)
    progress.start(10)
    # 树状视图
    tree = ttk.Treeview(frame, columns=('名称', '值'), show='headings', height=2)
    tree.heading('名称', text='名称')
    tree.heading('值', text='值')
    tree.insert('', 'end', values=('项目1', 100))
    tree.insert('', 'end', values=('项目2', 200))
    tree.grid(row=4, column=0, columnspan=3, pady=5)
    # 分隔线
    ttk.Separator(frame, orient='horizontal').grid(row=5, columnspan=3, sticky='ew', pady=5)
    # 笔记本(选项卡)
    notebook = ttk.Notebook(frame)
    tab1 = ttk.Frame(notebook)
    tab2 = ttk.Frame(notebook)
    notebook.add(tab1, text='选项卡1')
    notebook.add(tab2, text='选项卡2')
    notebook.grid(row=6, columnspan=3, sticky='ew')

    return frame

def change_theme(theme):
    """切换主题并更新界面"""
    style.theme_use(theme)
    print(f"当前主题: {theme}")

# 创建主窗口
root = tk.Tk()
root.title('ttk主题样式演示')

# 初始化样式对象
style = ttk.Style()
available_themes = style.theme_names()
current_theme = style.theme_use()
print("可用内置主题:", available_themes)

# 创建主题选择控件
theme_frame = ttk.Frame(root, padding=(10,5))
theme_frame.pack(fill='x')

ttk.Label(theme_frame, text="选择主题:").pack(side='left', padx=5)
theme_combobox = ttk.Combobox(
    theme_frame,
    values=list(available_themes),
    state='readonly'
)
theme_combobox.set(current_theme)
theme_combobox.pack(side='left', padx=5)
theme_combobox.bind('<<ComboboxSelected>>',
                   lambda e: change_theme(theme_combobox.get()))

# 创建演示组件
demo_frame = create_demo_widgets(root)

# 启动主循环
root.mainloop()

完毕!!感谢您的收看

----------★★跳转到历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具 NumPy Pygame

import tkinter as tk from tkinter import ttk from ttkbootstrap import Style import math class AnimatedCardCarousel: def __init__(self, root): self.root = root self.root.title("卡片堆叠式轮播(动画版)") self.root.geometry("800x500") # 创建卡片数据 self.cards = [ {"title": "卡片1", "content": "这是第一个卡片的内容,展示轮播效果", "color": "primary"}, {"title": "卡片2", "content": "第二个卡片的内容,支持平滑动画过渡", "color": "INFO"}, {"title": "卡片3", "content": "第三个卡片的内容,响应式设计", "color": "INFO"}, {"title": "卡片4", "content": "第四个卡片的内容,移动设备优先", "color": "INFO"}, {"title": "卡片5", "content": "第五个卡片的内容,使用ttkbootstrap", "color": "INFO"} ] # 当前显示的卡片索引 self.current_index = 0 # 动画状态 self.animating = False # 动画帧数 self.animation_frames = 25 # 当前动画帧 self.current_frame = 0 # 创建主容器 self.container = ttk.Frame(root, padding=20) self.container.pack(fill=tk.BOTH, expand=True) # 创建轮播容器 self.carousel_frame = ttk.Frame(self.container) self.carousel_frame.pack(fill=tk.BOTH, expand=True, padx=50, pady=20) # 创建卡片容器 self.cards_container = ttk.Frame(self.carousel_frame) self.cards_container.pack(fill=tk.BOTH, expand=True) # 创建底部控制面板 self.control_frame = ttk.Frame(self.container) self.control_frame.pack(fill=tk.X, pady=10) # 创建指示器 self.indicators_frame = ttk.Frame(self.control_frame) self.indicators_frame.pack(side=tk.LEFT, padx=10) # 创建按钮 self.prev_btn = ttk.Button( self.control_frame, text="上一个", command=self.prev_card, width=10, style="outline" ) self.prev_btn.pack(side=tk.LEFT, padx=5) self.next_btn = ttk.Button( self.control_frame, text="下一个", command=self.next_card, width=10, style="outline" ) self.next_btn.pack(side=tk.LEFT, padx=5) # 创建卡片 self.card_frames = [] for i, card_data in enumerate(self.cards): card = self.create_card(card_data, i) self.card_frames.append(card) # 创建指示器 self.create_indicators() # 初始显示 self.update_carousel() def create_card(self, card_data, index): """创建单个卡片""" # 卡片框架 card_frame = ttk.Frame( self.cards_container, style=f"{card_data['color']}.TFrame", borderwidth=2, relief="ridge" ) card_frame.pack_propagate(False) # 卡片标题 title_label = ttk.Label( card_frame, text=card_data["title"], style=f"{card_data['color']}.Inverse.TLabel", font=("Arial", 16, "bold"), padding=(15, 10, 15, 5) ) title_label.pack(fill=tk.X) # 卡片内容 content_label = ttk.Label( card_frame, text=card_data["content"], style=f"{card_data['color']}.TLabel", font=("Arial", 12), padding=(15, 5, 15, 15), wraplength=300 ) content_label.pack(fill=tk.BOTH, expand=True) # 卡片页脚 footer_frame = ttk.Frame(card_frame, style=f"{card_data['color']}.TFrame") footer_frame.pack(fill=tk.X, pady=5, padx=5) # 卡片编号 index_label = ttk.Label( footer_frame, text=f"卡片 {index+1}/{len(self.cards)}", style=f"{card_data['color']}.Inverse.TLabel", font=("Arial", 10) ) index_label.pack(side=tk.LEFT, padx=5) # 操作按钮 action_btn = ttk.Button( footer_frame, text="查看详情", style=f"{card_data['color']}.Outline.TButton" ) action_btn.pack(side=tk.RIGHT, padx=5, pady=5) return card_frame def create_indicators(self): """创建轮播指示器""" self.indicators = [] for i in range(len(self.cards)): indicator = ttk.Label( self.indicators_frame, text="●", font=("Arial", 12), cursor="hand2" ) indicator.pack(side=tk.LEFT, padx=3) indicator.bind("<Button-1>", lambda e, idx=i: self.go_to_card(idx)) self.indicators.append(indicator) def update_carousel(self): """更新轮播显示""" # 更新卡片位置和大小 for i, card in enumerate(self.card_frames): # 当前卡片 - 最大尺寸 if i == self.current_index: relx = 0.5 width = 400 height = 300 zorder = 100 # 前一个卡片 - 左侧较小尺寸 elif i == (self.current_index - 1) % len(self.cards): relx = 0.2 width = 300 height = 250 zorder = 50 # 后一个卡片 - 右侧较小尺寸 elif i == (self.current_index + 1) % len(self.cards): relx = 0.8 width = 300 height = 250 zorder = 50 # 其他卡片 - 隐藏 else: card.place_forget() continue # 应用动画效果 if self.animating: # 计算动画进度 (0.0 到 1.0) progress = self.current_frame / self.animation_frames # 使用缓动函数使动画更自然 ease_progress = self.ease_in_out_quad(progress) # 计算当前卡片的位置 current_relx = self.start_positions[i] + (relx - self.start_positions[i]) * ease_progress # 设置卡片位置 card.place(relx=current_relx, rely=0.5, anchor="center", width=width, height=height) else: # 无动画时直接设置位置 card.place(relx=relx, rely=0.5, anchor="center", width=width, height=height) # 设置层级 if zorder == 100: card.lift() else: card.lower() # 更新指示器状态 for i, indicator in enumerate(self.indicators): if i == self.current_index: indicator.configure(foreground="#ff9900") # 高亮当前指示器 else: indicator.configure(foreground="#cccccc") # 普通指示器 # 继续动画 if self.animating: self.current_frame += 1 if self.current_frame <= self.animation_frames: self.root.after(20, self.update_carousel) else: self.animating = False # 启用按钮 self.prev_btn["state"] = "normal" self.next_btn["state"] = "normal" def ease_in_out_quad(self, t): """二次缓动函数(缓入缓出)""" if t < 0.5: return 2 * t * t else: return -1 + (4 - 2 * t) * t def start_animation(self): """开始动画""" self.animating = True self.current_frame = 1 # 记录起始位置 self.start_positions = [] for i, card in enumerate(self.card_frames): # 获取卡片当前位置 try: relx = card.place_info()["relx"] if relx: self.start_positions.append(float(relx)) else: self.start_positions.append(0.5) except: self.start_positions.append(0.5) # 禁用按钮防止在动画过程中点击 self.prev_btn["state"] = "disabled" self.next_btn["state"] = "disabled" # 开始动画 self.update_carousel() def next_card(self): """显示下一张卡片""" if self.animating: return self.current_index = (self.current_index + 1) % len(self.cards) self.start_animation() def prev_card(self): """显示上一张卡片""" if self.animating: return self.current_index = (self.current_index - 1) % len(self.cards) self.start_animation() def go_to_card(self, index): """跳转到指定卡片""" if self.animating or index == self.current_index: return self.current_index = index self.start_animation() # 创建主窗口 style = Style(theme="cosmo") root = style.master # 创建轮播UI carousel = AnimatedCardCarousel(root) root.mainloop() 将这段代码中的五个卡片颜色改一下,最上方查看时的卡片主题为INFO,后面还未查看的主题为暗蓝色,其余功能不做修改,写出完整的代码
最新发布
07-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值