tkinter绘制组件31——支点标题引言布局函数结构标题标签布局框架绑定事件默认选值完整代码函数效果测试代码最终效果2026-10-30新样式github项目pip下载结语引言看到这四个字——支点标题是不是很疑惑其实……我写下来的时候也挺疑惑的。这个名称pivot取自winui的Pivot控件中文就是支点的意思。在winui中pivot类似于标题栏可以让使用者决定现在要看哪一个标题对应的窗口或者内容。当然在TinUI中支点标题仅仅是标题类似于单选组控件提高编写者对于窗口切换代码编写的高自由度。除此之外TinUI中的支点标题可以同时横向与纵向布局也是类似于单选组控件。虽然pivot和radiobox有很多相似之处但是对于使用者来说则是两个完全不同的交互控件。布局函数结构defadd_pivot(self,pos:tuple,fg#959595,bg,activefg#525252,activecolor#5969e0,content((a-title,tag1),(b-title,tag2),,(c-title,tag3)),font微软雅黑 16,padx10,pady10,commandNone):#绘制支点标题 pos::位置 fg::字体颜色 bg::创建时的保留参数 activefg::激活时字体颜色 activecolor::提示色 content::内容空字符串代表下一行 font::字体 padx::横向间距 pady::纵向间距 command::响应函数必须接受一个参数所选标题的tag 标题标签标题标签指的是content参数中每个常规元素的第二个元素这样标题被点击时返回的不是标题名称而是这个标签这里叫做tag。布局框架之前我们创建了单选组控件radiobox这里的布局逻辑与其相似不清楚的可以翻回那一篇文章看看。texts[]#[(text,tag,text-uid),...]count-1select-1#当前选定t_bboxNonenowx,nowypos#x坐标为左上角插入坐标y坐标为底部坐标uidpivotstr(id(content))lineself.create_line((pos[0],pos[1],pos[0]5,pos[1]),fillactivecolor,width3,capstyleround,tags(uid))foriincontent:count1#计数ifi:ift_bboxNone:#没有底部坐标数据nowypadyelse:nowyt_bbox[3]pady nowxpos[0]texts.append((\n,\n,None))continue#...这里面的line是随意位置创建的这个元素是标题提示线。for循环中省略的部分就是常规标题创建代码如下textself.create_text((nowx,nowy),fontfont,texti[0],fillfg,anchornw,tags(uid))t_bboxself.bbox(text)widtht_bbox[2]-t_bbox[0]nowxnowxwidthpadx texts.append((i[0],i[1],text))self.tag_bind(text,Enter,lambdaevent,numcount,tagtext:button_in(num,tag))self.tag_bind(text,Leave,lambdaevent,numcount,tagtext:button_out(num,tag))self.tag_bind(text,Button-1,lambdaevent,numcount,tagtext,tagnamei[1]:sel_it(num,tag,tagname))绑定事件上文中已经可以看到标题绑定了三种事件三种事件的处理如下defbutton_in(num,text_uid):ifnum!select:self.itemconfig(text_uid,fillactivefg)defbutton_out(num,text_uid):ifnum!select:self.itemconfig(text_uid,fillfg)defsel_it(num,text_uid,tag):nonlocalselectifnumselect:returnself.itemconfig(texts[select][2],fillfg)selectnum self.itemconfig(text_uid,fillactivefg)bboxself.bbox(text_uid)self.coords(line,(bbox[0],bbox[3]2,bbox[2],bbox[3]2))ifcommand!None:command(tag)注意的有两点sel_it中先恢复之前选定标题载重新设置当前选中select别忘了提示线移动重绘默认选值因为这个是标题内容因此不能向单选组控件一样有空值。在结尾加上一段代码。sel_it(0,texts[0][2],texts[0][1])完整代码函数defadd_pivot(self,pos:tuple,fg#959595,bg,activefg#525252,activecolor#5969e0,content((a-title,tag1),(b-title,tag2),,(c-title,tag3)),font微软雅黑 16,padx10,pady10,commandNone):#绘制支点标题defbutton_in(num,text_uid):ifnum!select:self.itemconfig(text_uid,fillactivefg)defbutton_out(num,text_uid):ifnum!select:self.itemconfig(text_uid,fillfg)defsel_it(num,text_uid,tag):nonlocalselectifnumselect:returnself.itemconfig(texts[select][2],fillfg)selectnum self.itemconfig(text_uid,fillactivefg)bboxself.bbox(text_uid)self.coords(line,(bbox[0],bbox[3]2,bbox[2],bbox[3]2))ifcommand!None:command(tag)texts[]#[(text,tag,text-uid),...]count-1select-1#当前选定t_bboxNonenowx,nowypos#x坐标为左上角插入坐标y坐标为底部坐标uidpivotstr(id(content))lineself.create_line((pos[0],pos[1],pos[0]5,pos[1]),fillactivecolor,width3,capstyleround,tags(uid))foriincontent:count1#计数ifi:ift_bboxNone:#没有底部坐标数据nowypadyelse:nowyt_bbox[3]pady nowxpos[0]texts.append((\n,\n,None))continuetextself.create_text((nowx,nowy),fontfont,texti[0],fillfg,anchornw,tags(uid))t_bboxself.bbox(text)widtht_bbox[2]-t_bbox[0]nowxnowxwidthpadx texts.append((i[0],i[1],text))self.tag_bind(text,Enter,lambdaevent,numcount,tagtext:button_in(num,tag))self.tag_bind(text,Leave,lambdaevent,numcount,tagtext:button_out(num,tag))self.tag_bind(text,Button-1,lambdaevent,numcount,tagtext,tagnamei[1]:sel_it(num,tag,tagname))sel_it(0,texts[0][2],texts[0][1])returntexts,uid效果测试代码#...b.add_pivot((1200,300),commandtest10)#...最终效果2026-10-30新样式添加点击响应颜色添加提示线过渡动画。github项目TinUI的github项目地址pip下载pipinstalltinui结语自我感觉这个比tkinter原生的标题框好看多了。tkinter创新
阅读完成 · 觉得有帮助?