tkinter绘制组件(2)——按钮

本文详述如何使用Tkinter库创建自定义的按钮组件,从基础的绘制到响应鼠标事件,实现类似Windows10原生按钮的样式,并提供了完整的代码示例。通过调整文字和矩形的绘制顺序,以及绑定鼠标事件来实现按钮的变色效果,打造现代化的用户界面。
摘要由CSDN通过智能技术生成
  • List item

引言

看过前一篇文章,就基本知道了TinUI的主体框架和开发宗旨。

接下来,我们将继续完善TinUI的组件绘制功能。先从最简单的按钮开始,毕竟按钮是界面交互中与使用者接触最多的组件,也是有着强大执行能力的组件,必须要让tkinter绘制出一个可以识别、好用、现代化的按钮UI组件。

目标

凡事都得定一个目标。

用TinUI会指出来的按钮,必须满足以下几个条件:

  1. 可以让人识别出来是按钮(这个很重要
  2. 可执行函数,即响应交互(废话)
  3. 对鼠标事件有反应

这是几个基础目标,那么TinUI的标准,就是Windows10的exe原生界面按钮。Windows10的原生按钮有以下几个特点:

  1. 常规背景色为:#E1E1E1
  2. 响应背景色为:#E5F1FB
  3. 响应边框色为:#82BDEB
  4. 可自定字体颜色

那么,现在开工。


绘制按钮

定义函数

在TinUI中,使用add_button添加按钮,其定义:

def add_button(self,pos:tuple,text:str,fg='black',bg='#E1E1E1',font=('微软雅黑',12),command=None):#绘制按钮
    '''
    pos::位置,(x,y)
    text::按钮文字
    fg::按钮文字颜色
    bg::按钮背景色
    font::文字字体
    command::响应的函数
    '''

绘制文字和按钮主体

因为使用画布绘制组件,一般来说,后创建的组件要比之前创建的组件位置层级要高,一般人会先绘制矩形,再添加文字。但这样有一个问题:我怎么知道矩形能否匹配文字?万一文字超出矩形范围不久“露馅”了?

在tkinter的Canvas中,通过绘制矩形和文字就可以绘制出一个虚拟按钮组件。但是,必须要先创建文字,再根据文字所占用的画布空间绘制矩形。代码如下:

button=self.create_text(pos,text=text,fill=fg,font=font,anchor='nw')
bbox=self.bbox(button)#获取文字占用的画布空间
#下面的代码主要是为了让人看起来更顺眼,使矩形能够更好地覆盖文字
x1,y1,x2,y2=bbox[0]-3,bbox[1]-3,bbox[2]+3,bbox[3]+3
#根据文字占位绘制矩形
back=self.create_rectangle((x1,y1,x2,y2),fill=bg,outline='grey')

这一番操作后,矩形会覆盖文字,那么还需要一个迷之操作来使文字到矩形上方:

self.tkraise(button)

相应鼠标事件

作为一个虚拟按钮,就必须要能够响应点击事件,执行函数:

self.tag_bind(button,'<Button-1>',command)

那么,为了提高按钮的“颜值”,当鼠标进入按钮时,按钮需要变色来使鼠标操作更有力度。当鼠标离开按钮时,按钮就要恢复其本身的颜色样式。接下来创建改变按钮样式的两个函数,这两个函数以内部函数创建。

def in_button(event):#鼠标进入
    self.itemconfig(back,fill='#E5F1FB',outline='#82BDEB')
def out_button(event):#鼠标离开
    self.itemconfig(back,fill=bg,outline='grey')

然后再绑定文字的事件:

一定是文字的事件,因为文字在矩形之上,矩形不会响应事件。

self.tag_bind(button,'<Enter>',in_button)
self.tag_bind(button,'<Leave>',out_button)

至此,我们完成通过TinUI绘制虚拟按钮组件的功能了。

完整函数代码

def add_button(self,pos:tuple,text:str,fg='black',bg='#E1E1E1',font=('微软雅黑',12),command=None):#绘制按钮
    def in_button(event):
        self.itemconfig(back,fill='#E5F1FB',outline='#82BDEB')
    def out_button(event):
        self.itemconfig(back,fill=bg,outline='grey')
    button=self.create_text(pos,text=text,fill=fg,font=font,anchor='nw')
    bbox=self.bbox(button)
    x1,y1,x2,y2=bbox[0]-3,bbox[1]-3,bbox[2]+3,bbox[3]+3
    back=self.create_rectangle((x1,y1,x2,y2),fill=bg,outline='grey')
    self.tag_bind(button,'<Button-1>',command)
    self.tag_bind(button,'<Enter>',in_button)
    self.tag_bind(button,'<Leave>',out_button)
    self.tkraise(button)
    return button

效果

按钮效果

测试代码:

def test(event):
    print('ok')
    a.title('TinUI Test')
    b.add_paragraph((50,200),'这是TinUI按钮触达的事件函数回显,此外,窗口标题也被改变')

a=Tk()
a.geometry('700x700+5+5')

b=TinUI(a,bg='white')
b.pack(fill='both',expand=True)
m=b.add_title((600,0),'TinUI is a test project for futher tin using')
b.add_title((40,670),'test TinUI scrolled',size=2,angle=24)
b.add_paragraph((20,290),'''     TinUI是基于tkinter画布开发的界面UI布局方案,作为tkinter拓展和TinEngine的拓展而存在。目前,TinUI尚处于开发阶段。如果想要使用完整的TinUI,敬请期待。''',
angle=-18)
b.add_paragraph((20,100),'下面的段落是测试画布的非平行字体显示效果,也是TinUI的简单介绍')
b.add_button((250,450),'测试按钮',command=test)

#a.after(5000,lambda:b.delete(m))
a.mainloop()

以下是按钮渲染的效果:

效果图中的代码,段落渲染部分没有使用 -angle 参数。

在这里插入图片描述

真的虚拟控件

不要认为这个按钮是我用 create_window 加上去的,看看它有没有句柄:

在这里插入图片描述

没有。很显然,我们成功创建了虚拟按钮。


2021-7-29新样式

在这里插入图片描述
与Label区分开来。

2021-12-4新样式

在这里插入图片描述
优化视觉效果;同时适配TinUI菜单 (现使用button2)。

2024-7-7新参数

可指定最小宽度和最大宽度,下图为限制minwidth=200
在这里插入图片描述


github项目

TinUI的github项目地址

结语

怎么样?玩tkinter,就应该玩出花样来。

🔆tkinter创新🔆

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值