Files
recommend/gui/styles.py

327 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
界面美化样式配置
提供统一的圆角设计和颜色主题
"""
import tkinter as tk
from tkinter import ttk
import customtkinter as ctk
class StyleConfig:
"""样式配置类"""
# 颜色主题
COLORS = {
'primary': '#3498db',
'primary_hover': '#2980b9',
'secondary': '#2ecc71',
'secondary_hover': '#27ae60',
'accent': '#e74c3c',
'accent_hover': '#c0392b',
'warning': '#f39c12',
'warning_hover': '#e67e22',
'info': '#9b59b6',
'info_hover': '#8e44ad',
'success': '#27ae60',
'success_hover': '#229954',
'danger': '#e74c3c',
'danger_hover': '#c0392b',
# 背景色
'bg_light': '#ffffff',
'bg_dark': '#2b2b2b',
'bg_card': '#f8f9fa',
'bg_card_dark': '#3b3b3b',
'bg_container': '#f0f0f0',
'bg_container_dark': '#1e1e1e',
# 文字色
'text_primary': '#2c3e50',
'text_primary_dark': '#ecf0f1',
'text_secondary': '#34495e',
'text_secondary_dark': '#bdc3c7',
'text_muted': '#7f8c8d',
'text_muted_dark': '#95a5a6',
# 边框色
'border': '#e0e0e0',
'border_dark': '#404040',
'border_light': '#f0f0f0',
'border_light_dark': '#555555',
}
# 圆角半径
CORNER_RADIUS = {
'small': 8,
'medium': 12,
'large': 15,
'xlarge': 20,
'xxlarge': 25,
}
# 字体配置
FONTS = {
'title': ('Arial', 22, 'bold'),
'subtitle': ('Arial', 18, 'bold'),
'heading': ('Arial', 16, 'bold'),
'body': ('Arial', 14),
'small': ('Arial', 12),
'tiny': ('Arial', 10),
}
# 间距配置
SPACING = {
'xs': 5,
'sm': 10,
'md': 15,
'lg': 20,
'xl': 25,
'xxl': 30,
}
def apply_rounded_theme():
"""应用圆角主题到CustomTkinter"""
# 设置全局主题
ctk.set_appearance_mode("light")
ctk.set_default_color_theme("blue")
# 注意CustomTkinter不支持类级别的configure方法
# 样式需要在创建组件时单独设置
print("✅ 圆角主题已应用")
def create_rounded_frame(parent, **kwargs):
"""创建圆角框架"""
colors = StyleConfig.COLORS
radius = StyleConfig.CORNER_RADIUS
default_kwargs = {
'corner_radius': radius['medium'],
'fg_color': (colors['bg_light'], colors['bg_dark']),
'border_width': 1,
'border_color': (colors['border'], colors['border_dark']),
}
default_kwargs.update(kwargs)
return ctk.CTkFrame(parent, **default_kwargs)
def create_rounded_button(parent, text, **kwargs):
"""创建圆角按钮"""
colors = StyleConfig.COLORS
radius = StyleConfig.CORNER_RADIUS
default_kwargs = {
'corner_radius': radius['medium'],
'fg_color': (colors['primary'], colors['primary_hover']),
'hover_color': (colors['primary_hover'], colors['primary']),
'text_color': ('#ffffff', '#ffffff'),
'font': StyleConfig.FONTS['body'],
}
default_kwargs.update(kwargs)
return ctk.CTkButton(parent, text=text, **default_kwargs)
def create_rounded_entry(parent, **kwargs):
"""创建圆角输入框"""
colors = StyleConfig.COLORS
radius = StyleConfig.CORNER_RADIUS
default_kwargs = {
'corner_radius': radius['medium'],
'fg_color': (colors['bg_card'], colors['bg_card_dark']),
'border_width': 1,
'border_color': (colors['border_light'], colors['border_light_dark']),
'font': StyleConfig.FONTS['body'],
'text_color': (colors['text_primary'], colors['text_primary_dark']),
}
default_kwargs.update(kwargs)
return ctk.CTkEntry(parent, **default_kwargs)
def create_rounded_label(parent, text, **kwargs):
"""创建圆角标签"""
colors = StyleConfig.COLORS
default_kwargs = {
'text_color': (colors['text_primary'], colors['text_primary_dark']),
'font': StyleConfig.FONTS['body'],
}
default_kwargs.update(kwargs)
return ctk.CTkLabel(parent, text=text, **default_kwargs)
def create_card_frame(parent, **kwargs):
"""创建卡片式框架"""
colors = StyleConfig.COLORS
radius = StyleConfig.CORNER_RADIUS
default_kwargs = {
'corner_radius': radius['large'],
'fg_color': (colors['bg_card'], colors['bg_card_dark']),
'border_width': 1,
'border_color': (colors['border'], colors['border_dark']),
}
default_kwargs.update(kwargs)
return ctk.CTkFrame(parent, **default_kwargs)
def create_accent_button(parent, text, color_type='primary', **kwargs):
"""创建强调色按钮"""
colors = StyleConfig.COLORS
radius = StyleConfig.CORNER_RADIUS
color_map = {
'primary': (colors['primary'], colors['primary_hover']),
'secondary': (colors['secondary'], colors['secondary_hover']),
'accent': (colors['accent'], colors['accent_hover']),
'warning': (colors['warning'], colors['warning_hover']),
'info': (colors['info'], colors['info_hover']),
'success': (colors['success'], colors['success_hover']),
'danger': (colors['danger'], colors['danger_hover']),
}
fg_color, hover_color = color_map.get(color_type, color_map['primary'])
default_kwargs = {
'corner_radius': radius['medium'],
'fg_color': fg_color,
'hover_color': hover_color,
'text_color': ('#ffffff', '#ffffff'),
'font': StyleConfig.FONTS['body'],
}
default_kwargs.update(kwargs)
return ctk.CTkButton(parent, text=text, **default_kwargs)
def apply_ttk_styles():
"""应用TTK样式"""
style = ttk.Style()
# 配置样式
style.configure('Rounded.TFrame',
relief='solid',
borderwidth=1,
background='#f8f9fa')
style.configure('Rounded.TLabelFrame',
relief='solid',
borderwidth=1,
background='#f8f9fa')
style.configure('Accent.TButton',
relief='flat',
borderwidth=0,
background='#3498db',
foreground='white',
font=('Arial', 12, 'bold'))
style.map('Accent.TButton',
background=[('active', '#2980b9'),
('pressed', '#1f618d')])
style.configure('Accent.TProgressbar',
background='#3498db',
troughcolor='#ecf0f1',
borderwidth=0,
lightcolor='#3498db',
darkcolor='#3498db')
def get_spacing(size='md'):
"""获取间距值"""
return StyleConfig.SPACING.get(size, StyleConfig.SPACING['md'])
def get_font(font_type='body'):
"""获取字体配置"""
return StyleConfig.FONTS.get(font_type, StyleConfig.FONTS['body'])
def get_color(color_name):
"""获取颜色值"""
return StyleConfig.COLORS.get(color_name, StyleConfig.COLORS['text_primary'])
def get_radius(size='medium'):
"""获取圆角半径"""
return StyleConfig.CORNER_RADIUS.get(size, StyleConfig.CORNER_RADIUS['medium'])
# 预定义的样式组合
STYLE_PRESETS = {
'card': {
'corner_radius': 20,
'fg_color': ('#ffffff', '#3b3b3b'),
'border_width': 1,
'border_color': ('#e0e0e0', '#404040'),
},
'button_primary': {
'corner_radius': 15,
'fg_color': ('#3498db', '#2980b9'),
'hover_color': ('#2980b9', '#1f618d'),
'text_color': ('#ffffff', '#ffffff'),
},
'button_secondary': {
'corner_radius': 15,
'fg_color': ('#2ecc71', '#27ae60'),
'hover_color': ('#27ae60', '#229954'),
'text_color': ('#ffffff', '#ffffff'),
},
'button_accent': {
'corner_radius': 15,
'fg_color': ('#e74c3c', '#c0392b'),
'hover_color': ('#c0392b', '#a93226'),
'text_color': ('#ffffff', '#ffffff'),
},
'input_field': {
'corner_radius': 12,
'fg_color': ('#f8f9fa', '#404040'),
'border_width': 1,
'border_color': ('#e0e0e0', '#555555'),
},
}
def apply_preset_style(widget, preset_name):
"""应用预设样式"""
if preset_name in STYLE_PRESETS:
style_config = STYLE_PRESETS[preset_name]
for key, value in style_config.items():
if hasattr(widget, key):
setattr(widget, key, value)
if __name__ == "__main__":
# 测试样式配置
root = tk.Tk()
root.title("样式测试")
root.geometry("400x300")
# 应用TTK样式
apply_ttk_styles()
# 创建测试框架
main_frame = ttk.Frame(root, style='Rounded.TFrame')
main_frame.pack(fill='both', expand=True, padx=20, pady=20)
# 创建测试按钮
test_button = ttk.Button(main_frame, text="测试按钮", style='Accent.TButton')
test_button.pack(pady=10)
# 创建测试标签框架
test_frame = ttk.LabelFrame(main_frame, text="测试框架", style='Rounded.TLabelFrame')
test_frame.pack(fill='both', expand=True, pady=10)
test_label = ttk.Label(test_frame, text="这是一个测试标签")
test_label.pack(pady=20)
root.mainloop()