tkinter绘制组件(25)——内部UI框架
引言
其实这就是在TinUI里面再嵌套一个BasicTinUI。
这有什么意义呢?其实就是让一个常规组件能够像添加一个子控件一样放置在一个UI框架之下,同时还可以通过TinUIXml来进行编写,省去了通过直接使用create_window
这类的函数将控件至于TinUI中,以及还要手动配置一些参数的麻烦。此外,这可以让在TinUI框架之下新建一个UI框架一键化。
这就好比tinengine拥有<tinframe>
标签一样。
布局
函数结构
def add_ui(self,pos:tuple,width:int=200,height:int=200,bg='white',scrollbar=False,region='man',anchor='nw'):#绘制BasicTinUI
'''
pos::位置
width::宽度
height::高度
bg::背景颜色
scrollbar::是否需要滚动条
region::可视范围,手动调整“main”,自动调整“auto”
anchor::对齐方向
'''
添加BasicTinUI
这个模仿TinUI的画布组件即可。
ui=BasicTinUI(self,bg=bg)
uid=self.create_window(pos,window=ui,width=width,height=height,anchor=anchor)
if scrollbar==True:
bbox=self.bbox(uid)
cid1=self.add_scrollbar((bbox[2]+5,bbox[1]),ui,bbox[3]-bbox[1])[-1]
cid2=self.add_scrollbar((bbox[0],bbox[3]+5),ui,bbox[2]-bbox[0],'x')[-1]
self.addtag_withtag(uid,cid1)
self.addtag_withtag(uid,cid2)
手动调整滚动范围
类似于TinUI的画布组件,我们需要为编写者留有自主选择的余地,因此我们仍然要创建一个可以手动更新可滚动范围的函数:
def re_scrollregion():#更新滚动范围
ui.config(scrollregion=ui.bbox('all'))
注意了,这里的变量名是子UI框架
ui
,而不是self
。
自动更新滚动范围
要是编写者像偷懒让GUI界面显得更加自动化,可以选自将region
参数赋予字符串“auto”,以此让BasicTinUI自动刷新滚动范围。当然,相比于TinUI的自动隐藏滚动条,这里的自动滚动功能要差一点,但是完全满足要求。
def __update():#更新宽高
try:
re_scrollregion()
except:
pass
else:
ui.after(1000,__update)
同时添加判断操作:
if scrollbar==True:
#...
if region=='man':#手动调节
pass
elif region=='auto':#自动调节
__update()
添加TinUIXml的绑定
为了方便编写者更好地使用内嵌UI框架,我们当然要先行创建TinUIXml类:
ui_xml=TinUIXml(ui)
这样就方便后续的使用了。
在TinUI的示例当中,就直接使用了TinUIXml来为ui控件添加内部组件。
完整代码函数
def add_ui(self,pos:tuple,width:int=200,height:int=200,bg='white',scrollbar=False,region='man',anchor='nw'):#绘制BasicTinUI
def __update():#更新宽高
try:
re_scrollregion()
except:
pass
else:
ui.after(1000,__update)
def re_scrollregion():#更新滚动范围
ui.config(scrollregion=ui.bbox('all'))
ui=BasicTinUI(self,bg=bg)
uid=self.create_window(pos,window=ui,width=width,height=height,anchor=anchor)
if scrollbar==True:
bbox=self.bbox(uid)
cid1=self.add_scrollbar((bbox[2]+5,bbox[1]),ui,bbox[3]-bbox[1])[-1]
cid2=self.add_scrollbar((bbox[0],bbox[3]+5),ui,bbox[2]-bbox[0],'x')[-1]
self.addtag_withtag(uid,cid1)
self.addtag_withtag(uid,cid2)
if region=='man':#手动调节
pass
elif region=='auto':#自动调节
__update()
ui_xml=TinUIXml(ui)
return ui,re_scrollregion,ui_xml,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, as they are drawn by tkinter canvas')
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()
uixml=b.add_ui((150,890),scrollbar=True,region='auto')[-2]
uixml.loadxml('''<tinui><line>
<button text='button in child tinui'></button>
<label text='you can use BasicTinUI in a father TinUI
by using
tinui.add_uid(...)'></label>
</line><line>
<label text='you can use
manual function re-region
also can use
auto function
just one
like
this'>
</label>
</line></tinui>''')
a.mainloop()
最终效果
github项目
pip下载
pip install tinui
结语
TinUI完成了所有基本组件的加入,现在可以替代tkinter原生窗口了,同时搭配TinUIXml使用更加方便!
🔆tkinter创新🔆