tkinter绘制组件(46)——分段按钮

发布时间:2026/10/4 9:46:28

tkinter绘制组件(46)——分段按钮 tkinter绘制组件46——分段按钮引言布局函数结构所有元素文本布局转到指定位置处理鼠标信号完整代码函数效果2026-10-3 样式更新github项目pip下载引言分段按钮可以通过按钮的形式对同目的功能进行分类。布局函数结构defadd_segmentbutton(self,pos:tuple,fg#191919,bg#EDEDED,activefg#181818,activebg#E5E5E5,onbg#FAFAFA,line#E5E5E5,sign#3041d8,font微软雅黑 12,content(A,B,C),commandNone,anchornw): pos::位置 fg::文本颜色 bg::背景色 activefg::响应时文本颜色 activebg::响应时背景色 onbg::选中时背景色 line::边框颜色 sign::提示符颜色 font::字体 content::内容 command::回调函数必须接受一个参数选中的按钮文本 anchor::对齐方向 所有元素由于分段按钮有多个部件构成且现在TinUI已经实现了完善的布局计算功能所以先将所有需要的元素全部创建出来。index-1outlineself.__ui_polygon(((0,0),(0,0)),fillline,outlineline,width9)uidTinUIString(fsegmentbutton-{outline})buttonidf{uid}-buttonself.itemconfig(outline,tagsuid)backself.__ui_polygon(((0,0),(0,0)),fillbg,outlinebg,width9,tagsuid)buttonself.__ui_polygon(((0,0),(0,0)),fill,outline,width9,tagsuid)button2self.__ui_polygon(((0,0),(0,0)),fillonbg,outlineonbg,width9,tagsuid)lineself.create_line((0,0,0,0),fillsign,width3,tagsuid,capstyleround,statehidden)self.itemconfig(button2,statehidden)maxwidth0texts[]foriincontent:textself.create_text((0,0),texti,fontfont,fillfg,anchorn,tags(uid,buttonid))texts.append(text)bboxself.bbox(text)maxwidthmax(maxwidth,bbox[2]-bbox[0])self.tag_bind(text,Enter,lambdae,texttext:mouse_in(text))self.tag_bind(text,Leave,lambdae,texttext:self.itemconfig(text,fillfg))self.tag_bind(text,Button-1,lambdae,texttext:__click(text))这里面分别是背景、边框、按钮文本、选择元素、选定元素、提示线。文本布局分段按钮采用水平等宽布局因此上面的代码中记录了maxwidth各按钮文本居中布局。endxmaxwidth/2foriintexts:self.coords(i,endx,0)endxmaxwidth10bboxself.bbox(buttonid)width(maxwidth10)*content.__len__()-10coord(0,bbox[1],width,bbox[1],width,bbox[3],0,bbox[3])self.coords(back,coord)coord(-1,bbox[1]-1,width1,bbox[1]-1,width1,bbox[3]1,-1,bbox[3]1)self.coords(outline,coord)转到指定位置self.__auto_anchor(uid,pos,anchor)处理鼠标信号由于选定和选择会同时存在因此这里使用了两个圆角矩形元素来响应鼠标事件。当鼠标选择文本时由button响应选定时由button2响应。鼠标的离开由整个控件告知button。defmouse_in(cid):bboxself.bbox(cid)centerx(bbox[0]bbox[2])/2halfwidthmaxwidth/2x1centerx-halfwidth x2centerxhalfwidth coord(x1,bbox[1],x2,bbox[1],x2,bbox[3],x1,bbox[3])self.coords(button,coord)self.itemconfig(button,fillactivebg,outlineactivebg)self.itemconfig(cid,fillactivefg)defon_leave(e):self.itemconfig(button,fill,outline)def__click(cid):nonlocalindexifindex-1:self.itemconfig(button2,statenormal)self.itemconfig(line,statenormal)ifcidindex:returnindexcid bboxself.bbox(cid)centerx(bbox[0]bbox[2])//2halfwidthmaxwidth/2x1centerx-halfwidth x2centerxhalfwidth coord(x1,bbox[1],x2,bbox[1],x2,bbox[3],x1,bbox[3])self.coords(button2,coord)self.coords(line,((bbox[0]bbox[2])/2-maxwidth/4,bbox[3]2,(bbox[0]bbox[2])/2maxwidth/4,bbox[3]2))ifcommand:command(self.itemcget(cid,text))完整代码函数defadd_segmentbutton(self,pos:tuple,fg#191919,bg#EDEDED,activefg#181818,activebg#E5E5E5,onbg#FAFAFA,line#E5E5E5,sign#3041d8,font微软雅黑 12,content(A,B,C),commandNone,anchornw):# 绘制一个选项按钮defmouse_in(cid):bboxself.bbox(cid)centerx(bbox[0]bbox[2])/2halfwidthmaxwidth/2x1centerx-halfwidth x2centerxhalfwidth coord(x1,bbox[1],x2,bbox[1],x2,bbox[3],x1,bbox[3])self.coords(button,coord)self.itemconfig(button,fillactivebg,outlineactivebg)self.itemconfig(cid,fillactivefg)defon_leave(e):self.itemconfig(button,fill,outline)def__click(cid):nonlocalindexifindex-1:self.itemconfig(button2,statenormal)self.itemconfig(line,statenormal)ifcidindex:returnindexcid bboxself.bbox(cid)centerx(bbox[0]bbox[2])//2halfwidthmaxwidth/2x1centerx-halfwidth x2centerxhalfwidth coord(x1,bbox[1],x2,bbox[1],x2,bbox[3],x1,bbox[3])self.coords(button2,coord)self.coords(line,((bbox[0]bbox[2])/2-maxwidth/4,bbox[3]2,(bbox[0]bbox[2])/2maxwidth/4,bbox[3]2))ifcommand:command(self.itemcget(cid,text))index-1outlineself.__ui_polygon(((0,0),(0,0)),fillline,outlineline,width9)uidTinUIString(fsegmentbutton-{outline})buttonidf{uid}-buttonself.itemconfig(outline,tagsuid)backself.__ui_polygon(((0,0),(0,0)),fillbg,outlinebg,width9,tagsuid)buttonself.__ui_polygon(((0,0),(0,0)),fill,outline,width9,tagsuid)button2self.__ui_polygon(((0,0),(0,0)),fillonbg,outlineonbg,width9,tagsuid)lineself.create_line((0,0,0,0),fillsign,width3,tagsuid,capstyleround,statehidden)self.itemconfig(button2,statehidden)maxwidth0texts[]foriincontent:textself.create_text((0,0),texti,fontfont,fillfg,anchorn,tags(uid,buttonid))texts.append(text)bboxself.bbox(text)maxwidthmax(maxwidth,bbox[2]-bbox[0])self.tag_bind(text,Enter,lambdae,texttext:mouse_in(text))self.tag_bind(text,Leave,lambdae,texttext:self.itemconfig(text,fillfg))self.tag_bind(text,Button-1,lambdae,texttext:__click(text))endxmaxwidth/2foriintexts:self.coords(i,endx,0)endxmaxwidth10bboxself.bbox(buttonid)width(maxwidth10)*content.__len__()-10coord(0,bbox[1],width,bbox[1],width,bbox[3],0,bbox[3])self.coords(back,coord)coord(-1,bbox[1]-1,width1,bbox[1]-1,width1,bbox[3]1,-1,bbox[3]1)self.coords(outline,coord)self.tag_bind(uid,Leave,on_leave)self.__auto_anchor(uid,pos,anchor)deltexts,endx,coord,bbox uid.layoutlambdax1,y1,x2,y2,expandFalse:self.__auto_layout(uid,(x1,y1,x2,y2),anchor)returnback,outline,button,button2,line,uid效果暗黑样式2026-10-3 样式更新添加了线性过渡动画。github项目TinUI的github项目地址pip下载pipinstalltinui
延伸阅读

更多相关文章

2026/10/4 9:46:28

GitHub日榜趋势系统:从数据采集到开源生态观测

1. 项目概述:这不是一份榜单,而是一套可复用的趋势观测系统 “GitHub 日榜趋势速报 | 2026-10-02”这个标题乍看像一条新闻推送,但作为连续追踪 GitHub 全站活跃度六年的从业者,我必须说——它背后藏着一套被严重低估的工程化能力…

2026/10/4 9:46:28

STAR-CCM+二维NACA翼型气动计算全流程:从几何建模到极曲线

1. 为什么用STAR-CCM算二维翼型——先把目标和思路理清楚1.1 二维翼型气动性能计算到底要算什么先说结论:NACA翼型的二维气动性能计算,是整个空气动力学入门绕不开的一关。无论你是在校学生做课程设计,还是在企业里做无人机螺旋桨、风机叶片、…

2026/10/4 9:41:28

Mininet SDN攻防实验:从确定性环境到免疫式防御

1. 为什么用Mininet做SDN攻防模拟——不是“玩具”,而是精准复现真实网络行为的手术刀很多人第一次看到“Mininet模拟DDoS攻击”这个说法,第一反应是:这不就是个教学玩具吗?真能反映实际网络里的攻击效果?我刚入行那会…

2026/10/4 10:56:32

云原生基础设施与AIOps大模型一体化工程实战解析

1. 一体化工程到底在解决什么问题先说自己最近这几年很直观的感受:传统运维团队的日常,基本上就是盯着监控大屏,被告警淹没,然后靠老师傅的经验逐条排查。你说辛苦吧,确实辛苦,但产出很低——大部分时间都在…

2026/10/4 10:56:32

微软淡化AI入口背后:Windows工作新系统的设置与避坑指南

1. 这次更新到底动了什么刀微软这几年在 AI 上的动作,说实话已经多到让人有点审美疲劳了。从最早把 Copilot 塞进 Edge 侧边栏,到后来往 Word、Excel、PowerPoint 里硬插一个对话窗口,再到 Windows 任务栏上那个时不时弹出来问你要不要帮忙的…

2026/10/4 10:56:32

Cursor插件开发核心:plugin.json契约与harness调度机制

1. “plugins”不是功能按钮,而是Cursor生态的神经突触你打开Cursor,点开设置里那个标着“Plugins”的标签页,第一反应可能是——这不就是个装插件的地方?跟VS Code一样,搜名字、点安装、重启生效。但如果你真这么理解…

2026/10/4 10:56:32

Linux云计算与AIOps大模型:云原生智能运维一体化实战

1. 云原生基础设施与智能运维一体化:这套课程真正解决什么问题先说说我为什么盯上这个方向。做了十几年 Linux 运维,又折腾了几年容器和云计算,最大的感受是:这个行业的技能栈正在发生一次很剧烈的迁移。过去我们聊运维&#xff0…

2026/10/4 10:51:32

软件测试笔试题核心考点拆解:从SQL到测试用例设计的高分答题思路

先说个可能让不少人意外的事实:软件测试工程师的笔试,很多时候比面试更筛人。面试还能靠表达和临场发挥撑一撑,笔试却是一张卷子直接暴露你的基本功、逻辑习惯和工程思维。我这些年既作为候选人刷过不少大厂的测试笔试题,也作为面…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑