Skip to content

Commit ce9ec2f

Browse files
committed
feat(theme): 更新主题应用逻辑
- 新增 EnhancedTheme 接口,扩展了原 Theme 接口的功能 - 重构 BaseTheme、ClamTheme、WindowsTheme 类以实现新接口 - 更新 ExtendedTk 和 ExtendedDialog 类以支持新主题 - 新增 EVENT_ENHANCED_THEME_CHANGED 事件用于主题变更通知
1 parent 80cb722 commit ce9ec2f

File tree

8 files changed

+55
-35
lines changed

8 files changed

+55
-35
lines changed

docs/profile.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
1. 打开配置文件:`~/.vcf_generator_lite.py`
5252
2. 添加配置代码:
5353
````python
54-
from tkinter import Misc, Tk
54+
from tkinter import Tk
5555
from tkinter.ttk import Style
5656
from typing import override
5757

@@ -60,17 +60,16 @@
6060

6161
class ClassicTheme(BaseTheme):
6262
@override
63-
def apply_theme(self, master: Misc, style: Style):
64-
super().apply_theme(master, style)
63+
def apply_tk(self, master: Tk, style: Style):
64+
super().apply_tk(master, style)
6565
style.theme_use("classic")
6666
style.configure("TButton", padding="1p", width=11)
6767
style.configure("Vertical.TScrollbar", arrowsize="9p")
6868
style.configure("DialogHeader.TFrame", relief="raised")
6969
style.configure("TextFrame.TEntry", padding=0, borderwidth="2p")
7070

7171
window_background = style.lookup("TFrame", "background")
72-
if isinstance(master, Tk):
73-
master.configure(background=window_background)
72+
master.configure(background=window_background)
7473
master.option_add("*Toplevel.background", window_background)
7574

7675

src/vcf_generator_lite/theme/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from vcf_generator_lite.util.environment import is_windows
2-
from vcf_generator_lite.util.tkinter.theme import Theme
2+
from vcf_generator_lite.util.tkinter.theme import EnhancedTheme
33

44
__all__ = ["create_platform_theme"]
55

66

7-
def create_platform_theme() -> Theme:
7+
def create_platform_theme() -> EnhancedTheme:
88
if is_windows:
99
from vcf_generator_lite.theme.widows_theme import WindowsTheme
1010
return WindowsTheme()
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
from abc import ABC
2-
from tkinter import Misc
2+
from tkinter import Tk, Toplevel
33
from tkinter.ttk import Style
44
from typing import override
55

6-
from vcf_generator_lite.util.tkinter.theme import Theme
6+
from vcf_generator_lite.util.tkinter.theme import EnhancedTheme
77

88

9-
class BaseTheme(Theme, ABC):
9+
class BaseTheme(EnhancedTheme, ABC):
1010

1111
@override
12-
def apply_theme(self, master: Misc, style: Style):
12+
def apply_tk(self, master: Tk, style: Style):
13+
# 防止编辑框将其他组件挤出窗口
1314
master.option_add("*TextFrame.Text.width", 0, "widgetDefault")
1415
master.option_add("*TextFrame.Text.height", 0, "widgetDefault")
16+
17+
@override
18+
def apply_window(self, master: Tk | Toplevel, style: Style): pass
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from tkinter import Misc, Tk
1+
from tkinter import Tk, Toplevel
22
from tkinter.font import nametofont
33
from tkinter.ttk import Style
44
from typing import override
@@ -8,10 +8,10 @@
88

99
class ClamTheme(BaseTheme):
1010
@override
11-
def apply_theme(self, master: Misc, style: Style):
12-
super().apply_theme(master, style)
11+
def apply_tk(self, master: Tk, style: Style):
12+
super().apply_tk(master, style)
1313
style.theme_use("clam")
14-
default_font = nametofont("TkMenuFont")
14+
default_font = nametofont("TkDefaultFont")
1515
default_font_size = int(default_font.actual("size"))
1616

1717
# 重写部分配置以适配高分屏
@@ -24,8 +24,9 @@ def apply_theme(self, master: Misc, style: Style):
2424
style.configure("DialogHeader.TFrame", relief="raised")
2525
style.configure("TextFrame.TEntry", padding=0, borderwidth="1.5p")
2626

27+
@override
28+
def apply_window(self, master: Tk | Toplevel, style: Style):
29+
super().apply_window(master, style)
2730
# 窗口背景色不会跟随主题变化,需要手动设置
2831
window_background = style.lookup("TFrame", "background")
29-
if isinstance(master, Tk):
30-
master.configure(background=window_background)
31-
master.option_add("*Toplevel.background", window_background)
32+
master.configure(background=window_background)

src/vcf_generator_lite/theme/widows_theme.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from tkinter import Misc
1+
from tkinter import Tk
22
from tkinter.font import nametofont
33
from tkinter.ttk import Style
44
from typing import override
@@ -8,11 +8,12 @@
88

99
class WindowsTheme(BaseTheme):
1010
@override
11-
def apply_theme(self, master: Misc, style: Style):
12-
super().apply_theme(master, style)
11+
def apply_tk(self, master: Tk, style: Style):
12+
super().apply_tk(master, style)
1313
style.theme_use("vista")
14-
default_font = nametofont("TkMenuFont")
14+
default_font = nametofont("TkDefaultFont")
1515
default_font_size = int(default_font.actual("size"))
16+
1617
# 重写部分配置以适配高分屏
1718
style.configure("TButton", padding="2.5p")
1819
style.configure("Treeview", rowheight=f"{default_font_size + 6}p")
@@ -26,4 +27,4 @@ def apply_theme(self, master: Misc, style: Style):
2627

2728
# Windows 7 中菜单默认不使用TkMenuFont,因此需要手动设置字体。
2829
menu_font = nametofont("TkMenuFont")
29-
master.option_add("*Menu.font", menu_font)
30+
master.option_add("*Menu.font", menu_font, "widgetDefault")
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from abc import ABC, abstractmethod
2-
from tkinter import Misc
2+
from tkinter import Tk, Toplevel
33
from tkinter.ttk import Style
44

55

6-
class Theme(ABC):
6+
class EnhancedTheme(ABC):
77
@abstractmethod
8-
def apply_theme(self, master: Misc, style: Style): pass
8+
def apply_tk(self, master: Tk, style: Style): pass
9+
10+
@abstractmethod
11+
def apply_window(self, master: Tk | Toplevel, style: Style): pass

src/vcf_generator_lite/window/base/__init__.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
from vcf_generator_lite import resources
88
from vcf_generator_lite.theme import create_platform_theme
99
from vcf_generator_lite.util.tkinter.misc import ScalingMiscExtension
10-
from vcf_generator_lite.util.tkinter.theme import Theme
10+
from vcf_generator_lite.util.tkinter.theme import EnhancedTheme
1111
from vcf_generator_lite.util.tkinter.window import CenterWindowExtension, GcWindowExtension, GeometryWindowExtension, \
1212
WindowExtension, WindowingSystemWindowExtension, withdraw_cm
13-
from vcf_generator_lite.window.base.constants import EVENT_EXIT
13+
from vcf_generator_lite.window.base.constants import EVENT_ENHANCED_THEME_CHANGED, EVENT_EXIT
1414

1515
__all__ = ["ExtendedTk", "ExtendedToplevel", "ExtendedDialog"]
1616
_logger = logging.getLogger(__name__)
@@ -49,6 +49,7 @@ def __apply_default_events(self):
4949

5050

5151
class ExtendedTk(Tk, AppWindowExtension, ABC):
52+
theme: EnhancedTheme
5253

5354
def __init__(self, **kw):
5455
# __init__中加载的配置文件中可能需要设置主题,因此必须先设置标志
@@ -66,8 +67,11 @@ def _configure_ui_withdraw(self):
6667
def __apply_default_icon(self):
6768
self.iconphoto(True, PhotoImage(master=self, data=resources.read_binary("images/icon-48.png")))
6869

69-
def set_theme(self, theme: Theme):
70-
theme.apply_theme(self, Style(self))
70+
def set_theme(self, theme: EnhancedTheme):
71+
self.theme = theme
72+
theme.apply_tk(self, Style(self))
73+
theme.apply_window(self, Style(self))
74+
self.event_generate(EVENT_ENHANCED_THEME_CHANGED, )
7175
self._theme_applied = True
7276

7377

@@ -76,11 +80,18 @@ def __init__(self, master: Tk | Toplevel, **kw):
7680
super().__init__(master, **kw)
7781
AppWindowExtension.__init__(self)
7882

83+
@override
84+
def _configure_ui_withdraw(self):
85+
super()._configure_ui_withdraw()
86+
self.__apply_theme()
7987

80-
class ExtendedDialog(Toplevel, AppWindowExtension, ABC):
81-
def __init__(self, master: Tk | Toplevel, **kw):
82-
super().__init__(master, **kw)
83-
AppWindowExtension.__init__(self)
88+
def __apply_theme(self):
89+
root: ExtendedTk = self.nametowidget(".")
90+
root.theme.apply_window(self, Style(self))
91+
root.bind(EVENT_ENHANCED_THEME_CHANGED, lambda _: root.theme.apply_window(self, Style(self)))
92+
93+
94+
class ExtendedDialog(ExtendedToplevel, ABC):
8495

8596
@override
8697
def _configure_ui_withdraw(self):
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
EVENT_EXIT = "<<Exit>>"
1+
EVENT_EXIT = "<<Exit>>"
2+
EVENT_ENHANCED_THEME_CHANGED = "<<EnhancedThemeChanged>>"

0 commit comments

Comments
 (0)