• tkinter绘制组件(32)——圆角按钮


    引言

    容我解释一下,这个圆角按钮(button2)之所以是新控件,而不是原理按钮元素的新样式,主要是有以下几个原因。

    1. 我觉得按钮(button)元素的方形样式还可以,没有一些人说的那么栏

    2. 样式风格差异较大,不适合作为元素样式升级

    3. 与其他爱好者达成妥协。。。

    虽然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::位置点对齐方向
        '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    按钮元素

    因为这次样式大改,但主要是样式代码,逻辑代码小小地修改一下就可以了。

    先绘制文本,获取其占位空间:

            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)
    
    • 1
    • 2
    • 3
    • 4

    边框与圆角

    这里,我们使用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)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    内背景要后于外背景绘制,减少覆盖样式代码。

    逻辑代码

    这段部分与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,'',on_click)
            self.tag_bind(button,'',in_button)
            self.tag_bind(button,'',out_button)
            self.tag_bind(back,'',on_click)
            self.tag_bind(back,'',in_button)
            self.tag_bind(back,'',out_button)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    完整代码函数

        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,'',on_click)
            self.tag_bind(button,'',in_button)
            self.tag_bind(button,'',out_button)
            self.tag_bind(back,'',on_click)
            self.tag_bind(back,'',in_button)
            self.tag_bind(back,'',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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    效果

    测试代码

    if __name__=='__main__':
        #...
        b.add_button2((1200,180),text='圆角按钮')
        #...
    
    • 1
    • 2
    • 3
    • 4

    最终效果

    在这里插入图片描述


    github项目

    TinUI的github项目地址

    pip下载

    pip install tinui
    
    • 1

    结语

    大家觉得这个圆角按钮(button2)和方形按钮(button)怎么样呢?

    此外,还有一个就是关于TinUI的暂停维护时间段。因为作者学业原因,有一段时间将暂停维护TinUI。

    TinUI网站

    🔆tkinter创新🔆

  • 相关阅读:
    hdlbits系列verilog解答(向量门操作)-14
    『精华文稿』基于NeRF的三维内容生成
    indexDB 本地数据库
    小程序进阶-env(safe-area-inset-bottom)的使用
    C++_pen_静态与常量
    MFC新建内部消息
    关于 ELEMENTOR 的常见问题
    Vue3 —— 常用 Composition API(二)(hook 函数、toRef 和 toRefs)
    LeetCode刷题小记 八、【回溯算法】
    后台开发核心技术与应用实践看书笔记(二):面向对象的C++
  • 原文地址:https://blog.csdn.net/tinga_kilin/article/details/125867560