什么是模板?
一句话
tkdeft 是零件,不是主题。
我们都知道矢量作图能做出许多高级的效果;但一旦想把它做成"换套配色就能用的主题库", 就得为每一种组合预先实现一遍,效果实现单一、扩展性差。 所以这里选择另一条路:只提供把矢量图变成控件的零件,具体长什么样由你的组件决定。
那"模板"指什么
指照着抄的参考实现。仓库里这些零件怎么组合成一个真正的组件库,
有一个现成的答案:tkfluent ——
按钮、徽标、输入框、滑块、面板、菜单……都是用 tkdeft 的零件搭出来的:
从模板到自己的库:四步
1. 把设计稿拆成"配色字典"
设计稿里的每个状态(rest / hover / pressed / disabled)都是一组颜色与几何。
把它们写成纯 dict,与绘制代码彻底分开:
BUTTON = {
"light": {
"rest": {"back_color": "#ffffff", "border_color": "#000000",
"border_opacity": 0.08, "radius": 6,
"text_color": "#1b1b1b"},
"hover": {"back_color": "#f9f9f9", "border_color": "#000000",
"border_opacity": 0.12, "radius": 6,
"text_color": "#1b1b1b"},
},
"dark": { ... },
}
2. 用绘制规格画出来
组件不再拼 SVG,只描述规格;SVG / 栅格两条路交给引擎:
class MyButtonCanvas(DCanvas):
def _draw(self, event=None):
super()._draw(event)
if not self.winfo_ismapped():
return
self.delete("all")
style = self.attributes[self.interaction_state()]
self.draw_roundrect(
0, 0, self.winfo_width(), self.winfo_height(), style["radius"],
fill=style["back_color"],
outline=style["border_color"], outline_opacity=style["border_opacity"],
)
3. 用 DDrawWidget 接事件
enter / button1 / isfocus 三个状态位由基类维护,interaction_state()
直接给出 rest / hover / pressed / disabled,你只管查字典。
4. 换主题 = 换字典 + 重绘
把"当前主题"存成一份字典,切换时改指针再 _draw() 一遍即可——
绘制层一行都不用动。tkfluent 的 FluThemeManager 做的就是这件事。
为什么不做成主题库
因为 svg 能实现很多漂亮的组件,而我套的模板可能对其它设计起不了太大作用。
所以我把这套设计当作模板放在这里,供其它设计者参考使用。
设计来源:https://pixso.cn/community/file/ItC5JH1TOwj15EeOPcY7LQ?from_share