引言
在该系列前面的几篇文章中,给出了TinUI的雏形效果。包括绘制按钮、绘制段落文字,以及本篇要讲的刷新TinUI的可视范围。
既然在第一篇文章中就谈到了刷新绘制组件的可视范围,那么为什么要写本篇文章呢?
几个小问题
对于最初的TinUI的刷新可视范围,有以下几个令人看着不爽的地方:
- 滚动条一直存在,即使可视范围不需要滚动,滚动条依旧存在,影响视觉感受
- 无法指定是否一直刷新,可能会占一定的内存
- 更新的灵敏度,默认是每隔一秒更新一次
特别强调:对于第三个问题,因为tkinter的画布必须要指定滚动范围才能使用滚动条,因此我不会对更新的灵敏度进行任何改进,仅提供可控的刷新间隔参数。
优化滚动
下面是TinUI初版的滚动刷新代码:
class TinUI(Canvas):
"""适用于Tin的高级画布组件"""
def __init__(self,master,**kw):
#...
self.update__()
def update__(self):#更新宽高
try:
bbox=self.bbox('all')
self.config(scrollregion=bbox)
except:
pass
finally:
self.after(1000,self.update__)
其中,自动刷新的代码为 update__ 函数。
指定是否自动刷新
在初始化TinUI时,提供一个参数:update:bool=True
,默认为自动更新可视范围。
在初始化的最后加入一个判断条件即可:
class TinUI(Canvas):
"""适用于Tin的高级画布组件"""
def __init__(self,master,update:bool=True,**kw):
#...
if update==True:#是否自动更新画布
self.update__()
def update__(self):#更新宽高
try:
bbox=self.bbox('all')
self.config(scrollregion=bbox)
except:
pass
finally:
self.after(1000,self.update__)
指定刷新间隔
在初始化TinUI时,提供一个参数:update_time:int=1000
,默认为1秒。
先将该参数变量赋予自身变量,再将自动刷新中时间间隔改为该变量:
class TinUI(Canvas):
"""适用于Tin的高级画布组件"""
def __init__(self,master,update:bool=True,update_time:int=1000,**kw):
#...
self.update_time=update_time
#...
def update__(self):#更新宽高
try:
bbox=self.bbox('all')
self.config(scrollregion=bbox)
except:
pass
finally:
self.after(self.update_time,self.update__)
滚动条自动控制是否显示
这涉及到使用者对TinUI的观赏程度,因为当可视范围不需要滚动条,而滚动条却一直存在,这在视觉层面很不爽。
在自动刷新的代码中,添加几个判断条件。
一:当长和宽小于或等于组件尺寸时,两个滚动条分别隐藏
二:当长和宽大于组件尺寸时,两个滚动条分别显示
注意到上面的“分别”两字,两个滚动条的操作是分开的,因为可视范围的长和宽可能有一个小于组件尺寸,一个大于组件尺寸的情况,因此分开操作更加符合实际。
下面对两个滚动条分别添加判断操作:
class TinUI(Canvas):
"""适用于Tin的高级画布组件"""
def __init__(self,master,update:bool=True,update_time:int=1000,**kw):
#...
if update==True:#是否自动更新画布
self.update__()
def update__(self):#更新宽高
try:
bbox=self.bbox('all')
width,height=bbox[2:]
#判断高度
if height<=self.winfo_height():
self.vbar.pack_forget()
else:
#使用before参数,旨在不影响画布和滚动条的布局位置
self.vbar.pack(before=self,side=RIGHT,fill=Y)
#判断宽度
if width<=self.winfo_width():
self.hbar.pack_forget()
else:
self.hbar.pack(side=BOTTOM,fill=X)
self.config(scrollregion=bbox)
except:
pass
finally:
self.after(self.update_time,self.update__)
至此,完成了对TinUI组件的可视化刷新优化。
实现的效果
测试代码
下面是测试代码:
def test(event):
a.title('TinUI Test')
b.add_paragraph((50,150),'这是TinUI按钮触达的事件函数回显,此外,窗口标题也被改变、首行标题缩进减小')
b.coords(m,100,0)
def test1(event):
b.coords(m1,0,580)
def test2(event):
b.coords(m,590,0)
b.coords(m1,0,700)
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')
m1=b.add_title((0,680),'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)
b.add_button((250,500),'缩进尾行',command=test1)
b.add_button((250,550),'拓宽',command=test2)
#写这一篇文章时,已经实现绘制Label组件
b.add_label((10,220),'这是由画布TinUI绘制的Label组件')
a.mainloop()
效果
2022-5-14分割线新样式
因为TinUI分割线控件(separate)的绘制过于简单,就没有专门的文章。最近我更新了其出现(创建)时的新样式,就在这篇文章更新。
- 圆角端点
- 动态出现
github项目
这里优化了刷新滚动,如果有更好的界面滚动功能,可以在下面的github地址中添加或改进。
结语
在完成本篇文章时,已经完成了对Label组件的绘制。最新的TinUI将呈现在github中。
🔆tkinter创新🔆