tkinter绘制组件(32)——圆角按钮
tkinter绘制组件(32)圆角按钮
引言
容我解释一下,这个圆角按钮(button2)之所以是新控件,而不是原理按钮元素的新样式,主要是有以下几个原因。
-
我觉得按钮(button)元素的方形样式还可以,没有一些人说的那么栏
-
样式风格差异较大,不适合作为元素样式升级
-
与其他爱好者达成妥协。。。
虽然TinUI圆角按钮的诞生有一点点争议,但是一个好消息是,逻辑代码几乎和button一样。所以我就可以抄写借鉴一番。
😏没办法,我是TinUI所有权全权拥有者,也是目前唯一一个TinUI知识产权所有者(TinUI内容100%)。
布局
函数结构
def add_button2(self,pos:tuple,text:str,fg='#1b1b1b',bg='#fbfbfb',line='#CCCCCC',linew=1,activefg='#5d5d5d',activebg='#f5f5f5',activeline='#e5e5e5',font=('微软雅黑',12),command=None,anchor='nw'):#绘制圆角按钮
'''
pos::位置
text::文本
fg::文本颜色
bg::背景颜色
line::边框颜色
linew::边框宽度
activefg::响应时文本颜色
activebg::响应时背景颜色
activeline::响应时边框颜色
font::字体
command::目标函数,需要接受一个event参数,command(*event)
anchor::位置点对齐方向
'''
按钮元素
因为这次样式大改,但主要是样式代码,逻辑代码小小地修改一下就可以了。
先绘制文本,获取其占位空间:
button=self.create_text(pos,text=text,fill=fg,font=font,anchor=anchor)
uid='button2-'+str(button)
self.itemconfig(button,tags=uid)
x1,y1,x2,y2=self.bbox(button)
边框与圆角
这里,我们使用tkinter画布的polygon
元素绘制圆角背景。
注意到我们有边框参数。对于tkinter画布而言,有宽度的元素,一般是边框向两边均延伸。所以说,当我们设置宽度为9时,实际上是向两边延伸了4.5个单位。那么我们的外边框和内边框的宽度查为2,则两者之间自带宽度差为1。
因此,linew
要减去一个单位。
linew-=1
outline_t=(x1-linew,y1-linew,x2+linew,y1-linew,x2+linew,y2+linew,x1-linew,y2+linew)
outline=self.create_polygon(outline_t,width=9,tags=uid,fill=line,outline=line)
back_t=(x1,y1,x2,y1,x2,y2,x1,y2)
back=self.create_polygon(back_t,width=7,tags=uid,fill=bg,outline=bg)
内背景要后于外背景绘制,减少覆盖样式代码。
逻辑代码
这段部分与button几乎一致,看一下就行了。
def in_button(event):
self.itemconfig(outline,outline=activeline,fill=activeline)
self.itemconfig(button,fill=activefg)
def out_button(event):
self.itemconfig(back,fill=bg,outline=bg)
self.itemconfig(outline,outline=line,fill=line)
self.itemconfig(button,fill=fg)
def on_click(event):
self.itemconfig(back,fill=activebg,outline=activebg)
self.itemconfig(button,fill=activefg)
self.after(500,lambda : out_button(None))
if command!=None:
command(event)
#...
self.tag_bind(button,'<Button-1>',on_click)
self.tag_bind(button,'<Enter>',in_button)
self.tag_bind(button,'<Leave>',out_button)
self.tag_bind(back,'<Button-1>',on_click)
self.tag_bind(back,'<Enter>',in_button)
self.tag_bind(back,'<Leave>',out_button)
完整代码函数
def add_button2(self,pos:tuple,text:str,fg='#1b1b1b',bg='#fbfbfb',line='#CCCCCC',linew=1,activefg='#5d5d5d',activebg='#f5f5f5',activeline='#e5e5e5',font=('微软雅黑',12),command=None,anchor='nw'):#绘制圆角按钮
def in_button(event):
self.itemconfig(outline,outline=activeline,fill=activeline)
self.itemconfig(button,fill=activefg)
def out_button(event):
self.itemconfig(back,fill=bg,outline=bg)
self.itemconfig(outline,outline=line,fill=line)
self.itemconfig(button,fill=fg)
def on_click(event):
self.itemconfig(back,fill=activebg,outline=activebg)
self.itemconfig(button,fill=activefg)
self.after(500,lambda : out_button(None))
if command!=None:
command(event)
def change_command(new_func):
nonlocal command
command=new_func
def disable(fg='#9d9d9d',bg='#f5f5f5'):
self.itemconfig(button,state='disable',fill=fg)
self.itemconfig(back,state='disable',disabledfill=bg)
def active():
self.itemconfig(button,state='normal')
self.itemconfig(back,state='normal')
out_button(None)
button=self.create_text(pos,text=text,fill=fg,font=font,anchor=anchor)
uid='button2-'+str(button)
self.itemconfig(button,tags=uid)
x1,y1,x2,y2=self.bbox(button)
linew-=1
outline_t=(x1-linew,y1-linew,x2+linew,y1-linew,x2+linew,y2+linew,x1-linew,y2+linew)
outline=self.create_polygon(outline_t,width=9,tags=uid,fill=line,outline=line)
back_t=(x1,y1,x2,y1,x2,y2,x1,y2)
back=self.create_polygon(back_t,width=7,tags=uid,fill=bg,outline=bg)
self.tag_bind(button,'<Button-1>',on_click)
self.tag_bind(button,'<Enter>',in_button)
self.tag_bind(button,'<Leave>',out_button)
self.tag_bind(back,'<Button-1>',on_click)
self.tag_bind(back,'<Enter>',in_button)
self.tag_bind(back,'<Leave>',out_button)
self.tkraise(button)
funcs=FuncList(3)
funcs.change_command=change_command
funcs.disable=disable
funcs.active=active
return button,back,line,funcs,uid
效果
测试代码
if __name__=='__main__':
#...
b.add_button2((1200,180),text='圆角按钮')
#...
最终效果
2024-7-7新参数
可指定最小宽度和最大宽度,下图为限制最小宽度minwidth=200
:
2024-7-31新参数
本来,button2
就像是button
的进化版,这次终于迎来了除了样式之外的区别,也是特点,那就是增加了对Segoe Fluent Icons
符号的支持。
目前并没有打算给
button
加上,感受下我精准的刀法。
新增参数icon
,使用Unicode编码字符,如\uE79E
。
参数compound
,确定符号相对于文本的位置,值应在'left','right','top','bottom'
中。
github项目
pip下载
pip install tinui
结语
大家觉得这个圆角按钮(button2)和方形按钮(button)怎么样呢?
此外,还有一个就是关于TinUI的暂停维护时间段。因为作者学业原因,有一段时间将暂停维护TinUI。
🔆tkinter创新🔆
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)