tkinter绘制组件(26)——横向翻页视图

引言

目前,TinUI已经完成了基本组件绘制,也就是说TinUI已经成熟,可以作为一个轻量型的窗口框架来使用。自从这一篇文章,也就是TinUI的第一个完全拓展型组件——翻页视图的出现,TinUI开始了对tkinter原生组件的补充和完善。

横向翻页视图并不存在于tkinter的原生组件中,其在winui中的名称为pipspager。不同于标签页,翻页视图提供了一个可顺序转化,也可以指定序号翻页的视图,用来在有限的地方创建更多的UI框架。

现在,开工吧。


布局

函数结构

    def add_pipspager(self,pos:tuple,width:int=200,height:int=200,bg='#f3f3f3',fg='#898989',buttonbg='#f8f8f8',num:int=2):#绘制翻页视图
    '''
    pos::位置
    width::视图宽度
    height::视图高度
    bg::视图背景
    fg::窗口序号标识符颜色
    buttonbg::按钮背景色
    num::BasicTinUI个数
    '''

创建辅助控件

翻页视图的辅助控件主要有两个:

  1. 一对翻页按钮

  2. 底部一栏序号标识符,就是若干个小点

首先来创建翻页按钮:

        startx=pos[0]+20#按钮与主窗口间隔
        doty=pos[1]+height+5#控制点的起始纵坐标
        leftbutton=self.add_button((startx-2,pos[1]+width/2),'<',fg=fg,bg=buttonbg,linew=0,activefg=buttonbg,activebg=fg,command=move_left,anchor='e')[-1]
        rightbutton=self.add_button((startx+width+2,pos[1]+width/2),'>',fg=fg,bg=buttonbg,linew=0,activefg=buttonbg,activebg=fg,command=move_right,anchor='w')[-1]
        uid='pipspager'+str(leftbutton)+str(rightbutton)
        self.addtag_withtag(uid,leftbutton)
        self.addtag_withtag(uid,rightbutton)

接着创建导航栏,我们选择使用画布来创建导航栏,毕竟对我来说,画布与文本框使用起来更顺手。

直接在循环结构里面创建导航序号标识符,这样方便于待会BasicTinUI框架与标识符一同创立,方便管理。

        #...
        uilist=list()#[(uiid-1,BasicTinUI-1,TinUIXml-1),(uiid-2,BasicTinUI-2,TinUIXml-2),...]
        dotlist=list()#[dot1,dot2,...]
        nowui=0#当前显示界面序号
        bar=Canvas(self,bg=bg,highlightthickness=0,relief='flat')#导航栏
        barid=self.create_window((startx,doty),window=bar,width=width,height=11,anchor='nw',tags=uid)
        dotx=3
        for i in range(0,num):
            dot=bar.create_oval((dotx,3,dotx+5,8),fill=fg,outline=fg,width=0)
            dotlist.append(dot)
            dotx+=13

此刻我们已经创建了两个列表,范别是UI框架列表,以及导航标识符列表。这些列表都是为了之后的功能能够直接获取这些画布对象。此外,我们还定义了nowui变量,用于确定当前显示的视图的序号。

TinUI的pipspager中序号从0开始。

创建视图

创建BasicTinUI视图的构成与创建内部框架一样,同样为了一键化建立TinUI与TinUIXml的联系,我们直接实例化TinUIXml:

        #...
        for i in range(0,num):
            ui=BasicTinUI(self,bg=bg)
            tinuixml=TinUIXml(ui)
            uiid=self.create_window((startx,pos[1]),window=ui,width=width,height=height,state='hidden',anchor='nw',tags=uid)
            uilist.append((uiid,ui,tinuixml))
            #...

uilist=[(ui-id,ui,ui-xml),…]

导航标识符的功能

先编写这一部分的代码,是因为导航标识符实际上是更加基础的辅助控件,其响应用户时间不会影响到翻页按钮。

先来创建一个基础函数:

        def __move_to(number):
            nonlocal nowui
            self.itemconfig(uilist[nowui][0],state='hidden')
            nowui=number
            self.itemconfig(uilist[nowui][0],state='normal')

样式绑定:

        def __dot_in(dote):
            bar.itemconfig(dote,width=3)
        def __dot_out(dote):
            if dotlist.index(dote)==nowui:
                pass
            else:
                bar.itemconfig(dote,width=0)

标识符选择:

        def __dot_select(dote):
            number=dotlist.index(dote)
            if number==nowui:
                pass
            else:
                __move_to(number)
                for i in dotlist:
                    if i==dote:
                        continue
                    else:
                        bar.itemconfig(i,width=0)

封装一遍开发者可用的move_to函数:

        def move_to(number):
            __dot_in(dotlist[nowui])
            __dot_select(dotlist[nowui])
            __move_to(nowui)

绑定标识符事件:

        #...
        for i in range(0,num):
            #...
            bar.tag_bind(dot,'<Enter>',lambda event,dote=dot:__dot_in(dote))
            bar.tag_bind(dot,'<Leave>',lambda event,dote=dot:__dot_out(dote))
            bar.tag_bind(dot,'<Button-1>',lambda event,dote=dot:__dot_select(dote))
        __dot_in(dotlist[nowui])
        __dot_select(dotlist[nowui])
        __move_to(nowui)

翻页按钮的功能

有了前面的铺垫,两个翻页按钮的功能很好完成,逻辑很简单。

以下是两个功能函数:

        def move_left(event):
            nonlocal nowui
            if nowui==0:
                pass
            else:
                __dot_in(dotlist[nowui-1])
                __dot_select(dotlist[nowui-1])
        def move_right(event):
            nonlocal nowui
            if nowui==len(uilist)-1:
                pass
            else:
                __dot_in(dotlist[nowui+1])
                __dot_select(dotlist[nowui+1])

虽然听起来很复杂,但是写起来也没什么。

完整代码函数

    def add_pipspager(self,pos:tuple,width:int=200,height:int=200,bg='#f3f3f3',fg='#898989',buttonbg='#f8f8f8',num:int=2):#绘制翻页视图
        def move_left(event):
            nonlocal nowui
            if nowui==0:
                pass
            else:
                __dot_in(dotlist[nowui-1])
                __dot_select(dotlist[nowui-1])
        def move_right(event):
            nonlocal nowui
            if nowui==len(uilist)-1:
                pass
            else:
                __dot_in(dotlist[nowui+1])
                __dot_select(dotlist[nowui+1])
        def __move_to(number):
            nonlocal nowui
            self.itemconfig(uilist[nowui][0],state='hidden')
            nowui=number
            self.itemconfig(uilist[nowui][0],state='normal')
        def move_to(number):
            __dot_in(dotlist[nowui])
            __dot_select(dotlist[nowui])
            __move_to(nowui)
        def __dot_in(dote):
            bar.itemconfig(dote,width=3)
        def __dot_out(dote):
            if dotlist.index(dote)==nowui:
                pass
            else:
                bar.itemconfig(dote,width=0)
        def __dot_select(dote):
            number=dotlist.index(dote)
            if number==nowui:
                pass
            else:
                __move_to(number)
                for i in dotlist:
                    if i==dote:
                        continue
                    else:
                        bar.itemconfig(i,width=0)
        startx=pos[0]+20#按钮与主窗口间隔
        uilist=list()#[(uiid-1,BasicTinUI-1,TinUIXml-1),(uiid-2,BasicTinUI-2,TinUIXml-2),...]
        doty=pos[1]+height+5#控制点的起始纵坐标
        dotlist=list()#[dot1,dot2,...]
        nowui=0#当前显示界面序号
        leftbutton=self.add_button((startx-2,pos[1]+width/2),'<',fg=fg,bg=buttonbg,linew=0,activefg=buttonbg,activebg=fg,command=move_left,anchor='e')[-1]
        rightbutton=self.add_button((startx+width+2,pos[1]+width/2),'>',fg=fg,bg=buttonbg,linew=0,activefg=buttonbg,activebg=fg,command=move_right,anchor='w')[-1]
        uid='pipspager'+str(leftbutton)+str(rightbutton)
        self.addtag_withtag(uid,leftbutton)
        self.addtag_withtag(uid,rightbutton)
        bar=Canvas(self,bg=bg,highlightthickness=0,relief='flat')#导航栏
        barid=self.create_window((startx,doty),window=bar,width=width,height=11,anchor='nw',tags=uid)
        dotx=3
        for i in range(0,num):
            ui=BasicTinUI(self,bg=bg)
            tinuixml=TinUIXml(ui)
            uiid=self.create_window((startx,pos[1]),window=ui,width=width,height=height,state='hidden',anchor='nw',tags=uid)
            uilist.append((uiid,ui,tinuixml))
            dot=bar.create_oval((dotx,3,dotx+5,8),fill=fg,outline=fg,width=0)
            dotlist.append(dot)
            dotx+=13
            bar.tag_bind(dot,'<Enter>',lambda event,dote=dot:__dot_in(dote))
            bar.tag_bind(dot,'<Leave>',lambda event,dote=dot:__dot_out(dote))
            bar.tag_bind(dot,'<Button-1>',lambda event,dote=dot:__dot_select(dote))
        __dot_in(dotlist[nowui])
        __dot_select(dotlist[nowui])
        __move_to(nowui)
        return uilist,dotlist,move_to,uid

效果

测试代码

#...
#TinUI现在的测试代码量有点大,所以就缩减剩下了必要部分
def test6():
    for i in range(0,5):
        num=i
        xml=f'''
<tinui><line><label text='这是第{num}个BasicTinUI组件'></label></line>
<line><button text='功能按钮' command='lambda event:print("第{i}个功能按钮")'></button>
<combobox width='80' text='可选测试' content='("{i}","其它选项")'></combobox></line></tinui>'''
        ppgl[i][2].loadxml(xml)

if __name__=='__main__':
    a=Tk()
    a.geometry('700x700+5+5')

    b=TinUI(a,bg='white')
    b.pack(fill='both',expand=True)
    #...
    ppgl=b.add_pipspager((400,890),num=5)[0]
    test6()

    a.mainloop()

最终效果

在这里插入图片描述

2022-8-8新样式

在这里插入图片描述

  • 小修标识符
  • 对于超过可视范围的标识符,会自动显示到对应范围

2022-8-19新样式

在这里插入图片描述

  • 使用新的翻页标识符< >◀ ▶
  • 页面标识符改用文本,减少粗糙度
  • 修复向左越界翻页的页面标识符显示问题

2023-1-9更新

在这里插入图片描述
添加翻页切换动画。因为顺序与画布对齐原因,向前和向后的翻页动作有些许不同。

2024-2-11新样式

在这里插入图片描述
优化翻页按钮


github项目

TinUI的github项目地址

pip下载

pip install tinui

结语

TinUI完成了所有基本组件的加入,现在可以替代tkinter原生窗口了,同时搭配TinUIXml使用更加方便!

TinUI即将步入3.0。

🔆tkinter创新🔆

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值