tkinter绘制组件(24)——画布

  • 引言
  • 布局
  • 函数结构
  • 添加画布
  • 滚动条绑定
  • 画布的滚动范围
  • 完整代码函数
  • 效果
  • 测试代码
  • 最终效果
  • github项目
  • pip下载

  • 结语


引言

这句话可能我已经说了很多遍了,那就是画布(Canvas)组件是tkinter中最强的存在,其属性、原生功能、可拓展性都是tkinter中其它组件无法比拟的。其中,可拓展性尤为突出。相比于tkinter的文本框,tkinter画布的操作自由度非常高。

正是因为tkinter画布有着强大的自定义功能,才诞生了TinUI框架。

因为tkinter文本框的拓展性,诞生了TinEngine富文本渲染引擎。

所以,我们会将画布引入TinUI中。


布局

函数结构

def add_canvas(self,pos:tuple,width:int=200,height:int=200,bg='white',outline='#808080',linew=1,scrollbar=False,anchor='nw'):#绘制画布
    '''
    pos::位置
    width::宽度
    height::盖度
    bg::背景颜色,画布颜色
    outline::边框颜色
    linew::边框宽度
    scrollbar::是否添加滚动条
    anchor::对齐方位
    '''

添加画布

之前我们将文本框组件引入了TinUI,这里做类似的处理:

canvas=Canvas(self,bg=bg,highlightthickness=linew,highlightbackground=outline,relief='flat')
        uid=self.create_window(pos,window=canvas,width=width,height=height,anchor=anchor)

滚动条绑定

画布的绑定与文本框和滚动条的绑定类似:

if scrollbar==True:
            bbox=self.bbox(uid)
            cid1=self.add_scrollbar((bbox[2]+5,bbox[1]),canvas,bbox[3]-bbox[1])[-1]
            cid2=self.add_scrollbar((bbox[0],bbox[3]+5),canvas,bbox[2]-bbox[0],'x')[-1]
            self.addtag_withtag(uid,cid1)
            self.addtag_withtag(uid,cid2)

画布的滚动范围

画布与文本框不同,我们需要为tkinter画布指定可以滚动的范围。以下有两种方案:

  1. 像TinUI一样实时刷新滚动范围
  2. 由编写者决定什么时候更新

综合考虑,既然由编写者来写TinUI框架,那么就把权限给编写者吧。

添加一个函数用于返回调用:

def re_scrollregion():#更新滚动范围
            canvas.config(scrollregion=canvas.bbox('all'))

完整代码函数

def add_canvas(self,pos:tuple,width:int=200,height:int=200,bg='white',outline='#808080',linew=1,scrollbar=False,anchor='nw'):#绘制画布
        def re_scrollregion():#更新滚动范围
            canvas.config(scrollregion=canvas.bbox('all'))
        canvas=Canvas(self,bg=bg,highlightthickness=linew,highlightbackground=outline,relief='flat')
        uid=self.create_window(pos,window=canvas,width=width,height=height,anchor=anchor)
        if scrollbar==True:
            bbox=self.bbox(uid)
            cid1=self.add_scrollbar((bbox[2]+5,bbox[1]),canvas,bbox[3]-bbox[1])[-1]
            cid2=self.add_scrollbar((bbox[0],bbox[3]+5),canvas,bbox[2]-bbox[0],'x')[-1]
            self.addtag_withtag(uid,cid1)
            self.addtag_withtag(uid,cid2)
        return canvas,re_scrollregion,uid

效果

测试代码

def test(event):
    a.title('TinUI Test')
    b.add_paragraph((50,150),'这是TinUI按钮触达的事件函数回显,此外,窗口标题也被改变、首行标题缩进减小')
    b.coords(m,100,5)
def test1(word):
    print(word)
def test2(event):
    ok1()
def test3(event):
    ok2()
def test4(event):
    from time import sleep
    for i in range(1,101):
        sleep(0.02)
        progressgoto(i)
def test5(result):
    b.itemconfig(scale_text,text='当前选值:'+str(result))

if __name__=='__main__':
    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 modern way to show tkinter widget in your application')
    m1=b.add_title((0,680),'test TinUI scrolled',size=2,angle=24)
    b.add_paragraph((20,290),'''     TinUI是基于tkinter画布开发的界面UI布局方案,作为tkinter拓展和TinEngine的拓展而存在。目前,TinUI已可应用于项目。''',
    angle=-18)
    b.add_paragraph((20,100),'下面的段落是测试画布的非平行字体显示效果,也是TinUI的简单介绍')
    b.add_button((250,450),'测试按钮',activefg='white',activebg='red',command=test,anchor='center')
    b.add_checkbutton((80,430),'允许TinUI测试',command=test1)
    b.add_label((10,220),'这是由画布TinUI绘制的Label组件')
    b.add_entry((250,330),350,'这里用来输入',command=print)
    b.add_separate((20,200),600)
    b.add_radiobutton((50,480),300,'sky is blue, water is blue, too. So, what is your heart',('red','blue','black'),command=test1)
    b.add_link((400,500),'TinGroup知识库','http://tinhome.baklib-free.com/')
    b.add_link((400,530),'执行print函数',print)
    _,ok1,_=b.add_waitbar1((500,220),bg='#CCCCCC')
    b.add_button((500,270),'停止等待动画',activefg='cyan',activebg='black',command=test2)
    bu1=b.add_button((700,200),'停止点状滚动条',activefg='white',activebg='black',command=test3)[1]
    bu2=b.add_button((700,250),'nothing button 2')[1]
    bu3=b.add_button((700,300),'nothing button 3')[1]
    b.add_labelframe((bu1,bu2,bu3),'box buttons')
    _,_,ok2,_=b.add_waitbar2((600,400))
    b.add_combobox((600,550),text='你有多大可能去珠穆朗玛峰',content=('20%','40%','60%','80%','100%','1000%'))
    b.add_button((600,480),text='测试进度条(无事件版本)',command=test4)
    _,_,_,progressgoto,_,_=b.add_progressbar((600,510))
    b.add_table((180,630),data=(('a','space fans over the\nworld','c'),('you\ncan','2','3'),('I','II','have a dream, then try your best to get it!')))
    b.add_paragraph((300,850),text='上面是一个表格')
    b.add_onoff((600,100))
    b.add_spinbox((680,100))
    b.add_scalebar((680,50),command=test5)
    scale_text,_=b.add_label((890,50),text='当前选值:2')
    b.add_info((680,140),info_text='this is info widget in TinUI')
    mtb=b.add_paragraph((0,720),'测试菜单(右键单击)')
    b.add_menubar(mtb,cont=(('command',print),('menu',test1),'-',('TinUI文本移动',test)))
    ttb=b.add_paragraph((0,800),'TinUI能做些什么?')
    b.add_tooltip(ttb,'很多很多')
    b.add_back(pos=(0,0),uids=(ttb,),bg='cyan')
    _,_,ok3,_=b.add_waitbar3((600,800),width=240)
    b.add_button((600,750),text='停止带状等待框',command=lambda event:ok3())
    textbox=b.add_textbox((890,100),text='这是文本输入框,当然,无法在textbox的参数中绑定横向滚动'+'\n换行'*30)[0]
    textbox['wrap']='none'
    b.add_scrollbar((1095,100),textbox)
    b.add_scrollbar((890,305),textbox,direction='x')
    b.add_listbox((890,430),data=('item1','item2','item3','item4\n item4.1\n item4.2\n item4.3\n itme4.4\n item4.5','item5 and item5.1 and item5.2 and item5.3'),
    command=print)
    cav,cavf,_=b.add_canvas((890,670),scrollbar=True)
    for i in range(1,15):
        cav.create_text((5,i*40),text='画布对象:'+str(i)*i,font='微软雅黑 12',anchor='nw')
    cavf()

    a.mainloop()

最终效果

python tkinter设置组件不可见 tkinter自定义组件_ci


github项目

TinUI的github项目地址

pip下载

pip install tinui

结语

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

🔆tkinter创新🔆