glass-ui 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
glass_ui-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jiyihao
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ recursive-include docs *.md
5
+ recursive-include examples *.py *.png *.ico
6
+
7
+ global-exclude __pycache__ *.py[cod] .DS_Store
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: glass-ui
3
+ Version: 0.1.0
4
+ Summary: Liquid-glass UI layer for tkinter on Windows: real desktop blur behind your window, plus fully self-drawn widgets.
5
+ Author: jiyihao
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jiyihao/glass-ui
8
+ Project-URL: Repository, https://github.com/jiyihao/glass-ui
9
+ Project-URL: Issues, https://github.com/jiyihao/glass-ui/issues
10
+ Project-URL: Changelog, https://github.com/jiyihao/glass-ui/releases
11
+ Keywords: tkinter,gui,glass,liquid-glass,glassmorphism,blur,acrylic,mica,windows,desktop,ui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Win32 (MS Windows)
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Topic :: Software Development :: User Interfaces
19
+ Classifier: Topic :: Multimedia :: Graphics
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: Pillow>=9.0
24
+ Dynamic: license-file
25
+
26
+ # glass-ui
27
+
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-2ea44f.svg)](https://github.com/jiyihao/glass-ui/blob/main/LICENSE)
29
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-3776ab.svg)]()
30
+ [![Platform](https://img.shields.io/badge/Platform-Windows-0078d4.svg)]()
31
+ [![Deps](https://img.shields.io/badge/Deps-Pillow%20only-8a2be2.svg)]()
32
+
33
+ **给 tkinter 用的液态玻璃(Liquid Glass)界面层。**
34
+
35
+ tkinter 本身没有任何模糊、半透明合成能力,所以 Python 桌面小工具默认长相都很朴素。
36
+ 这个库把「看起来像一块真玻璃」需要的东西都包好了:抓取窗口后方的真实桌面 → 高斯模糊
37
+ → 上色调色 → 把卡片/描边/按钮底面合成进同一张底图 → 整张铺成 Canvas 背景,
38
+ 再配一套完全自绘的控件。
39
+
40
+ 透出来的是**真实桌面内容**,不是渐变模拟。
41
+
42
+ ![示例](https://raw.githubusercontent.com/jiyihao/glass-ui/main/examples/dashboard.png)
43
+
44
+ > 不想写代码?[**下载 MemTidy.exe**](https://github.com/jiyihao/glass-ui/releases/latest)
45
+ > 直接体验这个库的成品效果 —— 单文件免安装,双击就跑(Windows)。
46
+
47
+ ---
48
+
49
+ ## 这个库到底在做什么
50
+
51
+ tkinter 的三个「看起来能用其实不行」的方案:
52
+
53
+ | 做法 | 为什么不行 |
54
+ |---|---|
55
+ | `wm_attributes("-alpha", 0.9)` | 整窗一起变透,**文字跟着发虚**,中文尤其明显 |
56
+ | `wm_attributes("-transparentcolor", "#010203")` | 挖洞,那块区域**连鼠标事件一起消失**,控件点不到 |
57
+ | `ttk` 自定义主题 | 只能换配色,做不出模糊 |
58
+
59
+ 所以只能自己合成。渲染管线是这样的:
60
+
61
+ ```
62
+ 窗口后方的桌面
63
+ │ ImageGrab / BitBlt (抓屏时用 WDA_EXCLUDEFROMCAPTURE 排除自身)
64
+ ▼
65
+ 高斯模糊 + 饱和度 ×2.05 + 深色面纱
66
+ │
67
+ ▼
68
+ 四角彩色氛围光(screen 混合) + 顶部镜面高光 + 极淡噪点
69
+ │
70
+ ▼
71
+ GlassEngine.compose()
72
+ ├─ 卡片外阴影(向下偏移 6px,模糊 14)
73
+ ├─ 玻璃层:标题栏渐亮带 + 卡片白 16/255 填充 + 双层描边
74
+ ├─ 每张卡片内部的顶部柔光
75
+ ├─ 你插入的自定义图层(进度条凹槽、徽章底…)
76
+ ├─ 窗口棱边:整圈亮边 + 上缘更亮
77
+ └─ 按钮底面(一般留空,按钮有自己的画布)
78
+ │
79
+ ▼
80
+ 一张 RGBA 底图 → 当 Canvas 背景铺上去
81
+ │
82
+ ▼
83
+ Canvas 上只画文字和交互图元(重绘开销极低)
84
+ ```
85
+
86
+ 窗口圆角由 `SetWindowRgn` 在系统层裁掉;无边框窗口补 `WS_EX_APPWINDOW`
87
+ 才能进任务栏和 Alt+Tab。这些都在库里。
88
+
89
+ ---
90
+
91
+ ## 安装
92
+
93
+ ```bash
94
+ pip install glass-ui
95
+ ```
96
+
97
+ 只依赖 Pillow。想改源码就用可编辑安装:
98
+
99
+ ```bash
100
+ git clone https://github.com/jiyihao/glass-ui.git
101
+ cd glass-ui
102
+ pip install -e .
103
+ ```
104
+
105
+ 或者直接把 `glass_ui/` 文件夹丢进你的项目里,不需要装任何东西。
106
+
107
+ 要求:Windows(用到了 Win32 接口)、Python 3.9+、Pillow 9+。
108
+ 没有 Pillow 时库不会崩,会自动退化成纯色直角界面。
109
+
110
+ ---
111
+
112
+ ## 快速开始
113
+
114
+ ```python
115
+ import tkinter as tk
116
+ from glass_ui import GlassWindow, GlassButton, FONT_UI
117
+
118
+ class Demo(GlassWindow):
119
+ TITLE = "Hello Glass"
120
+ WIN_W, WIN_H = 720, 420
121
+
122
+ def build_ui(self):
123
+ self.make_canvas() # 建主 Canvas + 绑定拖动
124
+ self.btn = GlassButton(self, "点我", self.on_click,
125
+ 24, 300, 120, 44, "primary")
126
+
127
+ def glass_cards(self): # 哪些矩形是卡片
128
+ return [(24, 80, 672, 190)]
129
+
130
+ def glass_slices(self): # 哪些子控件要背景切片
131
+ return [(self.btn, self.btn.x, self.btn.y, self.btn.w, self.btn.h)]
132
+
133
+ def draw_chrome(self): # 画字
134
+ cv = self.cv
135
+ cv.delete("all")
136
+ if self.bg_photo is not None:
137
+ cv.create_image(0, 0, image=self.bg_photo, anchor="nw")
138
+ cv.create_text(48, 120, text="你好,玻璃", anchor="w",
139
+ fill="#ffffff", font=(FONT_UI, 22, "bold"))
140
+
141
+ def on_click(self):
142
+ self.info("提示", "模糊的是窗口后面真实的桌面。")
143
+
144
+ root = tk.Tk()
145
+ Demo(root).run()
146
+ ```
147
+
148
+ 跑起来就有了圆角、无边框、可拖动、背后是真桌面的玻璃窗口。
149
+
150
+ ---
151
+
152
+ ## 五个钩子
153
+
154
+ `GlassWindow` 的子类只需要实现这几件事,其余(抓屏、模糊、圆角、拖动、
155
+ 任务栏、背景切片分发、弹窗)都由基类负责:
156
+
157
+ | 方法 | 作用 |
158
+ |---|---|
159
+ | `build_ui()` | 建 `self.cv`(调 `self.make_canvas()`)和所有控件 |
160
+ | `glass_cards()` | 返回 `[(x, y, w, h)]`,这些矩形会变成玻璃卡片 |
161
+ | `glass_decorators()` | 返回 `[fn(img) -> img]`,画必须带 alpha 的静态层 |
162
+ | `glass_slices()` | 返回 `[(控件, x, y, w, h)]`,基类把底图切给控件 |
163
+ | `draw_chrome()` | 在 `self.cv` 上画文字和交互图元 |
164
+
165
+ 还有一个可选钩子 `on_ready()`,在界面搭好、背景还没建时调用,适合塞首屏数据。
166
+
167
+ ### `glass_slices()` 为什么必须写
168
+
169
+ 每个控件都是一个子 Canvas。子 Canvas 有自己的底色,圆角之外的四角会露出一个
170
+ **深色方框**。解法是把主底图对应区域切一块贴给它 —— 这就是 `glass_slices()`。
171
+
172
+ 漏写某个控件的后果就是它周围出现一个黑方块。这个坑我们在弹窗按钮上也踩过。
173
+
174
+ ---
175
+
176
+ ## 控件
177
+
178
+ | 控件 | 说明 |
179
+ |---|---|
180
+ | `GlassButton` | 胶囊按钮,`primary` / `ghost` 两种;自带常态 / 悬停 / 按下三态贴图 |
181
+ | `IconButton` | 标题栏圆形图标按钮(最小化 / 关闭 / 帮助) |
182
+ | `GlassToggle` | iOS 风格开关,轨道渐变 + 滑块投影 + 球体明暗 |
183
+ | `GlassTable` | 自绘可滚动表格,行底纹是内缩圆角条;带 Treeview 的一个子集接口 |
184
+ | `GlassLog` | 只读日志,时间戳等宽字体,正文按 tag 上色 |
185
+ | `GlassWindow` | 无边框圆角窗口基类,附带 `ask()` / `info()` 玻璃弹窗 |
186
+
187
+ 表格和日志的 tag 颜色由类属性映射,库不认识你的 tag 叫什么:
188
+
189
+ ```python
190
+ table.ROW_FG = {"warn": C_ORANGE, "muted": "#949db0"} # tag -> 主列颜色
191
+ table.ROW_DOT = ("warn",) # 这些 tag 左边画圆点
192
+ table.NOTE_FG = {"warn": C_ORANGE} # tag -> 备注列颜色
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 调参
198
+
199
+ `GlassEngine` 上的类属性就是全部的旋钮:
200
+
201
+ | 参数 | 默认 | 效果 |
202
+ |---|---|---|
203
+ | `BLUR` | `30` | 模糊半径。太小像磨砂贴膜,太大看不出桌面内容 |
204
+ | `VEIL` | `0.74` | 深色面纱强度。越低越透、文字越难读 |
205
+ | `CARD_R` | `18` | 卡片圆角 |
206
+ | `WIN_R` | `26` | 整窗圆角(同时是 `SetWindowRgn` 的半径) |
207
+ | `TITLE_H` | `58` | 标题栏高度,`0` 表示不要标题栏底色 |
208
+
209
+ 具体到某个窗口:
210
+
211
+ ```python
212
+ app = MyWindow(root)
213
+ app.engine.VEIL = 0.62 # 想更透一点
214
+ app.engine.BLUR = 26
215
+ app.rebuild_background()
216
+ ```
217
+
218
+ 字号、配色在 `glass_ui/theme.py`,都是普通常量,直接改或覆盖即可。
219
+
220
+ ---
221
+
222
+ ## 示例
223
+
224
+ ```
225
+ examples/
226
+ ├─ dashboard.py 最小示例:一块"系统概览"面板,也是本页顶部那张图
227
+ └─ memtidy/ MemTidy 内存整理器 —— 真实项目,完整源码
228
+ ```
229
+
230
+ 两个都能直接跑:
231
+
232
+ ```bash
233
+ python examples/dashboard.py
234
+ python examples/memtidy/memtidy.py
235
+ ```
236
+
237
+ 都支持 `--shot out.png`:渲染完截一张图就退出,用来核对布局。
238
+ 调界面时这个模式比反复手动截图舒服得多。
239
+
240
+ `examples/memtidy/` 是一个能打包成 exe 的真实应用(PyInstaller 单文件 19 MB),
241
+ 里面有:内存卡的四级信息层次、进度条渐变填充、带状态点的进程表、整理进度实时回显。
242
+ 界面代码全部调库,本体只剩 Win32 内存接口和「画什么字」。
243
+
244
+ ---
245
+
246
+ ## 已知限制
247
+
248
+ - **只在 Windows 上能用。** 抓屏、圆角、任务栏、抓屏排除都是 Win32 接口。
249
+ - **Alt+Tab 切换回来会短暂看到旧背景。** 窗口重新可见时会重新抓屏(`<Map>` 事件),
250
+ 但抓屏+合成要几十毫秒。
251
+ - **透明区域不能点击** 这个问题本库不存在(用的是系统级圆角裁剪,不是挖洞),
252
+ 但窗口**内部**的圆角处(比如卡片圆角外)仍然是主 Canvas,正常接收事件。
253
+ - **`WDA_EXCLUDEFROMCAPTURE` 需要 Windows 10 2004+。** 更老的系统上抓屏会拍到自己。
254
+ - **性能**:一次 `rebuild_background()` 大约 40~60ms(900×640,抓屏 + 模糊 + 合成)。
255
+ 只在窗口出现、移动结束、尺寸变化时重建,平时不重建。
256
+ - 表格没有多选拖拽、没有列排序,够用但不完整。
257
+
258
+ ---
259
+
260
+ ## 踩过的坑
261
+
262
+ 写这个库的过程中踩到一批 tkinter / Pillow / Win32 的坑,全部记录在
263
+ [`docs/PITFALLS.md`](https://github.com/jiyihao/glass-ui/blob/main/docs/PITFALLS.md)。几条高频的:
264
+
265
+ - **`ImageDraw` 在 RGBA 图上不混合 alpha**,只是直接写像素。半透明图元必须先画到
266
+ 独立图层再 `alpha_composite`,否则 `convert("RGB")` 之后就是一个纯白实心块。
267
+ - **`create_polygon(..., smooth=True)` 会把胶囊画成菱形**:圆角半径接近半高时,
268
+ 贝塞尔的控制点会把圆弧拉直成 45° 斜边。
269
+ - **`ImageDraw.arc` 的包围盒是整个按钮**,画"高光弧"会变成一条横穿按钮的白线。
270
+ - **`Image.alpha_composite` 没有 `dest` 参数**,想在指定位置合成只能
271
+ `crop → composite → paste`。
272
+ - **子画布会盖住主画布上的图元**,画在子画布起点之后的分隔线永远看不见。
273
+ - **`tkfont.measure()` 在大字号下偏大十几像素**,用 `cv.bbox(item)` 取实测宽度。
274
+
275
+ ---
276
+
277
+ ## License
278
+
279
+ [MIT](https://github.com/jiyihao/glass-ui/blob/main/LICENSE)
@@ -0,0 +1,254 @@
1
+ # glass-ui
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-2ea44f.svg)](https://github.com/jiyihao/glass-ui/blob/main/LICENSE)
4
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-3776ab.svg)]()
5
+ [![Platform](https://img.shields.io/badge/Platform-Windows-0078d4.svg)]()
6
+ [![Deps](https://img.shields.io/badge/Deps-Pillow%20only-8a2be2.svg)]()
7
+
8
+ **给 tkinter 用的液态玻璃(Liquid Glass)界面层。**
9
+
10
+ tkinter 本身没有任何模糊、半透明合成能力,所以 Python 桌面小工具默认长相都很朴素。
11
+ 这个库把「看起来像一块真玻璃」需要的东西都包好了:抓取窗口后方的真实桌面 → 高斯模糊
12
+ → 上色调色 → 把卡片/描边/按钮底面合成进同一张底图 → 整张铺成 Canvas 背景,
13
+ 再配一套完全自绘的控件。
14
+
15
+ 透出来的是**真实桌面内容**,不是渐变模拟。
16
+
17
+ ![示例](https://raw.githubusercontent.com/jiyihao/glass-ui/main/examples/dashboard.png)
18
+
19
+ > 不想写代码?[**下载 MemTidy.exe**](https://github.com/jiyihao/glass-ui/releases/latest)
20
+ > 直接体验这个库的成品效果 —— 单文件免安装,双击就跑(Windows)。
21
+
22
+ ---
23
+
24
+ ## 这个库到底在做什么
25
+
26
+ tkinter 的三个「看起来能用其实不行」的方案:
27
+
28
+ | 做法 | 为什么不行 |
29
+ |---|---|
30
+ | `wm_attributes("-alpha", 0.9)` | 整窗一起变透,**文字跟着发虚**,中文尤其明显 |
31
+ | `wm_attributes("-transparentcolor", "#010203")` | 挖洞,那块区域**连鼠标事件一起消失**,控件点不到 |
32
+ | `ttk` 自定义主题 | 只能换配色,做不出模糊 |
33
+
34
+ 所以只能自己合成。渲染管线是这样的:
35
+
36
+ ```
37
+ 窗口后方的桌面
38
+ │ ImageGrab / BitBlt (抓屏时用 WDA_EXCLUDEFROMCAPTURE 排除自身)
39
+ ▼
40
+ 高斯模糊 + 饱和度 ×2.05 + 深色面纱
41
+ │
42
+ ▼
43
+ 四角彩色氛围光(screen 混合) + 顶部镜面高光 + 极淡噪点
44
+ │
45
+ ▼
46
+ GlassEngine.compose()
47
+ ├─ 卡片外阴影(向下偏移 6px,模糊 14)
48
+ ├─ 玻璃层:标题栏渐亮带 + 卡片白 16/255 填充 + 双层描边
49
+ ├─ 每张卡片内部的顶部柔光
50
+ ├─ 你插入的自定义图层(进度条凹槽、徽章底…)
51
+ ├─ 窗口棱边:整圈亮边 + 上缘更亮
52
+ └─ 按钮底面(一般留空,按钮有自己的画布)
53
+ │
54
+ ▼
55
+ 一张 RGBA 底图 → 当 Canvas 背景铺上去
56
+ │
57
+ ▼
58
+ Canvas 上只画文字和交互图元(重绘开销极低)
59
+ ```
60
+
61
+ 窗口圆角由 `SetWindowRgn` 在系统层裁掉;无边框窗口补 `WS_EX_APPWINDOW`
62
+ 才能进任务栏和 Alt+Tab。这些都在库里。
63
+
64
+ ---
65
+
66
+ ## 安装
67
+
68
+ ```bash
69
+ pip install glass-ui
70
+ ```
71
+
72
+ 只依赖 Pillow。想改源码就用可编辑安装:
73
+
74
+ ```bash
75
+ git clone https://github.com/jiyihao/glass-ui.git
76
+ cd glass-ui
77
+ pip install -e .
78
+ ```
79
+
80
+ 或者直接把 `glass_ui/` 文件夹丢进你的项目里,不需要装任何东西。
81
+
82
+ 要求:Windows(用到了 Win32 接口)、Python 3.9+、Pillow 9+。
83
+ 没有 Pillow 时库不会崩,会自动退化成纯色直角界面。
84
+
85
+ ---
86
+
87
+ ## 快速开始
88
+
89
+ ```python
90
+ import tkinter as tk
91
+ from glass_ui import GlassWindow, GlassButton, FONT_UI
92
+
93
+ class Demo(GlassWindow):
94
+ TITLE = "Hello Glass"
95
+ WIN_W, WIN_H = 720, 420
96
+
97
+ def build_ui(self):
98
+ self.make_canvas() # 建主 Canvas + 绑定拖动
99
+ self.btn = GlassButton(self, "点我", self.on_click,
100
+ 24, 300, 120, 44, "primary")
101
+
102
+ def glass_cards(self): # 哪些矩形是卡片
103
+ return [(24, 80, 672, 190)]
104
+
105
+ def glass_slices(self): # 哪些子控件要背景切片
106
+ return [(self.btn, self.btn.x, self.btn.y, self.btn.w, self.btn.h)]
107
+
108
+ def draw_chrome(self): # 画字
109
+ cv = self.cv
110
+ cv.delete("all")
111
+ if self.bg_photo is not None:
112
+ cv.create_image(0, 0, image=self.bg_photo, anchor="nw")
113
+ cv.create_text(48, 120, text="你好,玻璃", anchor="w",
114
+ fill="#ffffff", font=(FONT_UI, 22, "bold"))
115
+
116
+ def on_click(self):
117
+ self.info("提示", "模糊的是窗口后面真实的桌面。")
118
+
119
+ root = tk.Tk()
120
+ Demo(root).run()
121
+ ```
122
+
123
+ 跑起来就有了圆角、无边框、可拖动、背后是真桌面的玻璃窗口。
124
+
125
+ ---
126
+
127
+ ## 五个钩子
128
+
129
+ `GlassWindow` 的子类只需要实现这几件事,其余(抓屏、模糊、圆角、拖动、
130
+ 任务栏、背景切片分发、弹窗)都由基类负责:
131
+
132
+ | 方法 | 作用 |
133
+ |---|---|
134
+ | `build_ui()` | 建 `self.cv`(调 `self.make_canvas()`)和所有控件 |
135
+ | `glass_cards()` | 返回 `[(x, y, w, h)]`,这些矩形会变成玻璃卡片 |
136
+ | `glass_decorators()` | 返回 `[fn(img) -> img]`,画必须带 alpha 的静态层 |
137
+ | `glass_slices()` | 返回 `[(控件, x, y, w, h)]`,基类把底图切给控件 |
138
+ | `draw_chrome()` | 在 `self.cv` 上画文字和交互图元 |
139
+
140
+ 还有一个可选钩子 `on_ready()`,在界面搭好、背景还没建时调用,适合塞首屏数据。
141
+
142
+ ### `glass_slices()` 为什么必须写
143
+
144
+ 每个控件都是一个子 Canvas。子 Canvas 有自己的底色,圆角之外的四角会露出一个
145
+ **深色方框**。解法是把主底图对应区域切一块贴给它 —— 这就是 `glass_slices()`。
146
+
147
+ 漏写某个控件的后果就是它周围出现一个黑方块。这个坑我们在弹窗按钮上也踩过。
148
+
149
+ ---
150
+
151
+ ## 控件
152
+
153
+ | 控件 | 说明 |
154
+ |---|---|
155
+ | `GlassButton` | 胶囊按钮,`primary` / `ghost` 两种;自带常态 / 悬停 / 按下三态贴图 |
156
+ | `IconButton` | 标题栏圆形图标按钮(最小化 / 关闭 / 帮助) |
157
+ | `GlassToggle` | iOS 风格开关,轨道渐变 + 滑块投影 + 球体明暗 |
158
+ | `GlassTable` | 自绘可滚动表格,行底纹是内缩圆角条;带 Treeview 的一个子集接口 |
159
+ | `GlassLog` | 只读日志,时间戳等宽字体,正文按 tag 上色 |
160
+ | `GlassWindow` | 无边框圆角窗口基类,附带 `ask()` / `info()` 玻璃弹窗 |
161
+
162
+ 表格和日志的 tag 颜色由类属性映射,库不认识你的 tag 叫什么:
163
+
164
+ ```python
165
+ table.ROW_FG = {"warn": C_ORANGE, "muted": "#949db0"} # tag -> 主列颜色
166
+ table.ROW_DOT = ("warn",) # 这些 tag 左边画圆点
167
+ table.NOTE_FG = {"warn": C_ORANGE} # tag -> 备注列颜色
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 调参
173
+
174
+ `GlassEngine` 上的类属性就是全部的旋钮:
175
+
176
+ | 参数 | 默认 | 效果 |
177
+ |---|---|---|
178
+ | `BLUR` | `30` | 模糊半径。太小像磨砂贴膜,太大看不出桌面内容 |
179
+ | `VEIL` | `0.74` | 深色面纱强度。越低越透、文字越难读 |
180
+ | `CARD_R` | `18` | 卡片圆角 |
181
+ | `WIN_R` | `26` | 整窗圆角(同时是 `SetWindowRgn` 的半径) |
182
+ | `TITLE_H` | `58` | 标题栏高度,`0` 表示不要标题栏底色 |
183
+
184
+ 具体到某个窗口:
185
+
186
+ ```python
187
+ app = MyWindow(root)
188
+ app.engine.VEIL = 0.62 # 想更透一点
189
+ app.engine.BLUR = 26
190
+ app.rebuild_background()
191
+ ```
192
+
193
+ 字号、配色在 `glass_ui/theme.py`,都是普通常量,直接改或覆盖即可。
194
+
195
+ ---
196
+
197
+ ## 示例
198
+
199
+ ```
200
+ examples/
201
+ ├─ dashboard.py 最小示例:一块"系统概览"面板,也是本页顶部那张图
202
+ └─ memtidy/ MemTidy 内存整理器 —— 真实项目,完整源码
203
+ ```
204
+
205
+ 两个都能直接跑:
206
+
207
+ ```bash
208
+ python examples/dashboard.py
209
+ python examples/memtidy/memtidy.py
210
+ ```
211
+
212
+ 都支持 `--shot out.png`:渲染完截一张图就退出,用来核对布局。
213
+ 调界面时这个模式比反复手动截图舒服得多。
214
+
215
+ `examples/memtidy/` 是一个能打包成 exe 的真实应用(PyInstaller 单文件 19 MB),
216
+ 里面有:内存卡的四级信息层次、进度条渐变填充、带状态点的进程表、整理进度实时回显。
217
+ 界面代码全部调库,本体只剩 Win32 内存接口和「画什么字」。
218
+
219
+ ---
220
+
221
+ ## 已知限制
222
+
223
+ - **只在 Windows 上能用。** 抓屏、圆角、任务栏、抓屏排除都是 Win32 接口。
224
+ - **Alt+Tab 切换回来会短暂看到旧背景。** 窗口重新可见时会重新抓屏(`<Map>` 事件),
225
+ 但抓屏+合成要几十毫秒。
226
+ - **透明区域不能点击** 这个问题本库不存在(用的是系统级圆角裁剪,不是挖洞),
227
+ 但窗口**内部**的圆角处(比如卡片圆角外)仍然是主 Canvas,正常接收事件。
228
+ - **`WDA_EXCLUDEFROMCAPTURE` 需要 Windows 10 2004+。** 更老的系统上抓屏会拍到自己。
229
+ - **性能**:一次 `rebuild_background()` 大约 40~60ms(900×640,抓屏 + 模糊 + 合成)。
230
+ 只在窗口出现、移动结束、尺寸变化时重建,平时不重建。
231
+ - 表格没有多选拖拽、没有列排序,够用但不完整。
232
+
233
+ ---
234
+
235
+ ## 踩过的坑
236
+
237
+ 写这个库的过程中踩到一批 tkinter / Pillow / Win32 的坑,全部记录在
238
+ [`docs/PITFALLS.md`](https://github.com/jiyihao/glass-ui/blob/main/docs/PITFALLS.md)。几条高频的:
239
+
240
+ - **`ImageDraw` 在 RGBA 图上不混合 alpha**,只是直接写像素。半透明图元必须先画到
241
+ 独立图层再 `alpha_composite`,否则 `convert("RGB")` 之后就是一个纯白实心块。
242
+ - **`create_polygon(..., smooth=True)` 会把胶囊画成菱形**:圆角半径接近半高时,
243
+ 贝塞尔的控制点会把圆弧拉直成 45° 斜边。
244
+ - **`ImageDraw.arc` 的包围盒是整个按钮**,画"高光弧"会变成一条横穿按钮的白线。
245
+ - **`Image.alpha_composite` 没有 `dest` 参数**,想在指定位置合成只能
246
+ `crop → composite → paste`。
247
+ - **子画布会盖住主画布上的图元**,画在子画布起点之后的分隔线永远看不见。
248
+ - **`tkfont.measure()` 在大字号下偏大十几像素**,用 `cv.bbox(item)` 取实测宽度。
249
+
250
+ ---
251
+
252
+ ## License
253
+
254
+ [MIT](https://github.com/jiyihao/glass-ui/blob/main/LICENSE)