资讯详情

资讯详情

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
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →