☰
tkinter绘制组件(31)——支点标题
2026/10/31 10:40:26 网站建设 项目流程

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',padx=10,pady=10,command=None):#绘制支点标题''' pos::位置 fg::字体颜色 bg::创建时的保留参数 activefg::激活时字体颜色 activecolor::提示色 content::内容,空字符串代表下一行 font::字体 padx::横向间距 pady::纵向间距 command::响应函数,必须接受一个参数,所选标题的tag '''

标题标签

标题标签指的是content参数中,每个常规元素的第二个元素,这样标题被点击时返回的不是标题名称,而是这个标签,这里叫做tag。

布局框架

之前我们创建了单选组控件(radiobox),这里的布局逻辑与其相似,不清楚的可以翻回那一篇文章看看。

texts=[]#[(text,tag,text-uid),...]count=-1select=-1#当前选定t_bbox=Nonenowx,nowy=pos#x坐标为左上角插入坐标,y坐标为底部坐标uid='pivot'+str(id(content))line=self.create_line((pos[0],pos[1],pos[0]+5,pos[1]),fill=activecolor,width=3,capstyle='round',tags=(uid))foriincontent:count+=1#计数ifi=='':ift_bbox==None:#没有底部坐标数据nowy+=padyelse:nowy=t_bbox[3]+pady nowx=pos[0]texts.append(('\n','\n',None))continue#...

这里面的line是随意位置创建的,这个元素是标题提示线。

for循环中,省略的部分就是常规标题创建,代码如下:

text=self.create_text((nowx,nowy),font=font,text=i[0],fill=fg,anchor='nw',tags=(uid))t_bbox=self.bbox(text)width=t_bbox[2]-t_bbox[0]nowx=nowx+width+padx texts.append((i[0],i[1],text))self.tag_bind(text,'<Enter>',lambdaevent,num=count,tag=text:button_in(num,tag))self.tag_bind(text,'<Leave>',lambdaevent,num=count,tag=text:button_out(num,tag))self.tag_bind(text,'<Button-1>',lambdaevent,num=count,tag=text,tagname=i[1]:sel_it(num,tag,tagname))

绑定事件

上文中已经可以看到标题绑定了三种事件,三种事件的处理如下:

defbutton_in(num,text_uid):ifnum!=select:self.itemconfig(text_uid,fill=activefg)defbutton_out(num,text_uid):ifnum!=select:self.itemconfig(text_uid,fill=fg)defsel_it(num,text_uid,tag):nonlocalselectifnum==select:returnself.itemconfig(texts[select][2],fill=fg)select=num self.itemconfig(text_uid,fill=activefg)bbox=self.bbox(text_uid)self.coords(line,(bbox[0],bbox[3]+2,bbox[2],bbox[3]+2))ifcommand!=None:command(tag)

注意的有两点:

  1. sel_it中,先恢复之前选定标题,载重新设置当前选中select

  2. 别忘了提示线移动(重绘)

默认选值

因为这个是标题内容,因此不能向单选组控件一样有空值。

在结尾加上一段代码。

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',padx=10,pady=10,command=None):#绘制支点标题defbutton_in(num,text_uid):ifnum!=select:self.itemconfig(text_uid,fill=activefg)defbutton_out(num,text_uid):ifnum!=select:self.itemconfig(text_uid,fill=fg)defsel_it(num,text_uid,tag):nonlocalselectifnum==select:returnself.itemconfig(texts[select][2],fill=fg)select=num self.itemconfig(text_uid,fill=activefg)bbox=self.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_bbox=Nonenowx,nowy=pos#x坐标为左上角插入坐标,y坐标为底部坐标uid='pivot'+str(id(content))line=self.create_line((pos[0],pos[1],pos[0]+5,pos[1]),fill=activecolor,width=3,capstyle='round',tags=(uid))foriincontent:count+=1#计数ifi=='':ift_bbox==None:#没有底部坐标数据nowy+=padyelse:nowy=t_bbox[3]+pady nowx=pos[0]texts.append(('\n','\n',None))continuetext=self.create_text((nowx,nowy),font=font,text=i[0],fill=fg,anchor='nw',tags=(uid))t_bbox=self.bbox(text)width=t_bbox[2]-t_bbox[0]nowx=nowx+width+padx texts.append((i[0],i[1],text))self.tag_bind(text,'<Enter>',lambdaevent,num=count,tag=text:button_in(num,tag))self.tag_bind(text,'<Leave>',lambdaevent,num=count,tag=text:button_out(num,tag))self.tag_bind(text,'<Button-1>',lambdaevent,num=count,tag=text,tagname=i[1]:sel_it(num,tag,tagname))sel_it(0,texts[0][2],texts[0][1])returntexts,uid

效果

测试代码

#...b.add_pivot((1200,300),command=test10)#...

最终效果

2026-10-30新样式

添加点击响应颜色;添加提示线过渡动画。


github项目

TinUI的github项目地址

pip下载

pipinstalltinui

结语

自我感觉,这个比tkinter原生的标题框好看多了。

🔆tkinter创新🔆

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询