tkinter绘制组件(52)——标签栏
- 引言
- 布局
- 函数结构
- 整体
- 标签元素
- 标签添加
- 标签删除
- 效果
- github项目
- pip下载
引言
标签栏labels用于呈现若干特定属性的文本,相比于普通文本,标签栏有着精简、突出的文本意义。
布局
函数结构
defadd_labels(self,pos:tuple,fg='#000000',bg='#fdfdfd',activefg='#1b1b1b',activebg='#f9f9f9',outline='#eeeeee',font=None,widget=True,anchor='nw',command=None):# 绘制一个标签栏""" widget::是否显示添加按钮 command::添加按钮的回调函数,需要返回`标签名[, 删除回调函数]` """整体
TinUI的标签栏采用两种交互模式,一种是仅显示特定标签;另一种是允许通过控件本身交互进行标签的增删。无论是哪一种交互模式,控件主体布局都是一致的。
逻辑上,标签栏水平展示所有标签,每个标签文本使用“胶囊”形状的图形元素包裹。对于第二种交互模式,需要额外一个添加按钮,通过某种回调交互添加新的标签,所有标签都添加在末尾。另外,添加标签时,可以选择是否允许标签删除,并产生相应回调。
由于标签栏在实现上相比于过往的那些控件并不复杂,因此下文主要以代码为主。
标签元素
添加按钮与常规标签几乎一模一样,因此本文省略添加按钮的绘制。
text=self.create_text(endx,endy,text=label,font=font,fill=fg,tags=uid)textuid=f'label-text-{text}'self.addtag_withtag(textuid,text)bbox=self.bbox(text)width=(bbox[2]-bbox[0])*2//3height=bbox[3]-bbox[1]ifheight%2==0:height+=1linew=height+self.scale_value(2)back=self.create_line(endx-width,endy,endx+width,endy,fill=bg,width=height,tags=(uid,textuid),capstyle='round')line=self.create_line(endx-width,endy,endx+width,endy,fill=outline,width=linew,tags=(uid,textuid),capstyle='round')self.tag_raise(back)self.tag_raise(text)这里确保
linew是奇数,是因为tkinter的绘制特性,奇数更对称好看。
如果允许标签被删除,就添加删除提示符,并且微调标签文本位置向左。
ifcallable(oncancel):self.move(text,-self.scale_value(3),0)cancelt=self.create_text(bbox[2]-self.scale_value(2),endy,anchor='w',text='\uE711',font=segoe_font,tags=(uid,textuid),fill=bg)self.tag_bind(cancelt,'<Enter>',on_enter)self.tag_bind(cancelt,'<Leave>',on_leave)self.tag_bind(cancelt,'<Button-1>',on_click)labell.append(cancelt)这里的
oncancel是回调函数,如果可被调用,则标识该标签可被删除。
标签添加
bbox=self.bbox(line)width=bbox[2]-bbox[0]self.__auto_anchor(textuid,(endx,endy),'w')self.dtag(textuid)endx+=width# 调整下一个的插入位置labell.append(labels.__len__())# 当前位置ifwidget:self.move(plusuid,width,0)labels.append(labell)
labels是列表[[text, back, line, [cancelt], index], ...]。
标签删除
oncancel(label)self.delete(text,back,line,cancelt)index=labell[-1]foritemsinlabels[index:]:items[-1]-=1foriteminitems[:-1]:self.move(item,-width,0)ifwidget:self.move(plusuid,-width,0)endx-=width labels.pop(index)对于被删除标签之后的标签,需要对它们的位置序号-1。
效果
github项目
TinUI的github项目地址
pip下载
pipinstalltinui