engines.cache · 图片缓存
绘制结果缓存。
为什么需要
tkfluent 的一次 hover 会让同一个 RoundRectSpec 被反复绘制(rest→hover 的
渐变动画最多几十帧,多个同尺寸按钮更是完全同参)。没有缓存时每次都要重新
光栅化并新建 PhotoImage——实测这正是端到端耗时的大头。
缓存键
(引擎名, spec)。spec 是 frozen dataclass,天然可哈希。
生命周期与"空图"陷阱
PhotoImage 绑定在具体的 Tk 解释器上,且 一旦被垃圾回收,引用它的
canvas item 会变成空白。因此这里刻意 不做 LRU 淘汰,而是采用
"像素预算 + 满了就不再写入"的策略:已经发出去的图片永远保持存活,
新的、缓存不下的规格就退化为"每次都重新渲染"——只损失速度,绝不损坏画面。
解释器用 id() 作键(_tkinter.tkapp 不支持 weakref),并用对象同一性
校验,避免 id 复用导致的串台。
ImageCache
单个 Tk 解释器对应的绘制结果缓存。
键是 (引擎名, 图元类型, spec);值是 (PhotoImage, 像素数)。
所有方法都是线程安全的(由模块级锁保护),可以直接在多线程里查询统计。
:param budget: 像素预算;超出后新规格不再写入缓存(见模块文档里的说明)
源代码位于: tkdeft\engines\cache.py
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
budget
property
writable
像素预算。
pixels
property
当前缓存占用的像素数。
clear()
清空缓存并返回被清掉的条目数。
.. warning::
已经发出去的 :class:~tkinter.PhotoImage 仍然由调用方(画布)持有,
因此清空缓存不会让画面立刻变空白;真正的风险在于之后画布重新引用
同一规格时会重新渲染。
源代码位于: tkdeft\engines\cache.py
105 106 107 108 109 110 111 112 113 114 115 116 | |
get(key)
取缓存图片;未命中返回 None(同时累计命中率统计)。
源代码位于: tkdeft\engines\cache.py
70 71 72 73 74 75 76 77 78 | |
put(key, photo, pixels)
写入缓存;超出预算时 静默放弃(已发出的图片保持有效)。
:param key: (引擎名, 图元类型, spec)
:param photo: tkinter.PhotoImage
:param pixels: 该图片占用的像素数(用于预算核算)
:returns: 是否真的写入了缓存;False 表示这次只能"每次重新渲染"
源代码位于: tkdeft\engines\cache.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
reset_stats()
把命中/未命中/溢出计数清零(不动缓存内容)。
源代码位于: tkdeft\engines\cache.py
145 146 147 | |
stats()
这条缓存的统计信息(条目数、像素占用、命中率、溢出次数)。
源代码位于: tkdeft\engines\cache.py
132 133 134 135 136 137 138 139 140 141 142 143 | |
cache_stats(master=None)
缓存统计,便于性能诊断。
:param master: 只看某个解释器;None 表示汇总所有解释器
(额外带一个 interpreters 字段)
::
>>> cache_stats()
{'interpreters': 1, 'entries': 62, 'pixels': 169244, 'budget': 8000000,
'hits': 178, 'misses': 99, 'hit_rate': 0.642, 'overflow': 0}
源代码位于: tkdeft\engines\cache.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
clear_cache(master=None)
清空缓存,返回被清掉的条目数。
:param master: 只清某个解释器的缓存;None 表示清空全部解释器
.. warning:: 清空后,仍然存在于画布上的 item 会因为图片被回收而变空白。 仅在确实要重建整个界面时调用。
源代码位于: tkdeft\engines\cache.py
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | |
get_cache(master)
取(必要时创建)某个 Tk 解释器对应的缓存。
:param master: 任意 Tk 控件,或 tkapp 本身
:returns: 绑定到该解释器的 :class:ImageCache
源代码位于: tkdeft\engines\cache.py
196 197 198 199 200 201 202 | |
set_cache_budget(pixels)
设置像素预算,并立即应用到所有已存在的解释器缓存。
:param pixels: 预算(像素数);None 表示恢复默认
:data:DEFAULT_PIXEL_BUDGET(注意:并不是"不限制")
源代码位于: tkdeft\engines\cache.py
222 223 224 225 226 227 228 229 230 231 232 | |