引言
在Win32程序中,通常会用到标题框来划定一系列功能组件的界限,或者是区分每一部分的组件对应的主题。在tkinter中,LabelFrame
就只这样的一个组件,让人对界面的感觉很整齐、明了,而且还便于操作。
那么,在TinUI中,我们也要实现这样的一个绘制组件,来使TinUI的部分界面整齐划一。
思路
不同于其它GUI框架中的LabelFrame,TinUI中的LabelFrame并不是作为一个父组件来使用,这是TinUI框架自身的性质决定的——无法进行pack/gird排版。因此,TinUI创建LabelFrame的思路跟其它的框架有不一样,是先等需要划入的组件全部绘制完后,再指定LabelFrame需要包含的组件,TinUI根据这些组件的范围,自动绘制LabelFrame。
因此,TinUI中的LabelFrame,是TinUI目前第一个需要通过指定其它绘制组件进行绘制的控件。
布局
函数结构
TinUI中,LabelFrame采取与其它组件略微不同的函数参数构造。
def add_labelframe(self,widgets:tuple=(),title='',fg='#A8A8A8',bg=''):#绘制标题框
'''
widgets::所涵盖的组件对应的画布对象的列表
title::标题文字
fg::边框及标题颜色
bg::标题背景和组件背景填充色
'''
边框
这个很好处理,通过获取所需要包含的组件在画布中的位置,再位置计算得出边框正确的绘制范围。
先任意获取其中一个组件的范围,作为初始值。再依次获取组件画布对象的范围,通过比较各个范围的最大值或最小值,来刷新需要绘制边框的范围:
sx,sy,ex,ey=self.bbox(widgets[0])#获取直接的起始位置
for i in widgets:
nsx,nsy,nex,ney=self.bbox(i)
sx=nsx if nsx<sx else sx
sy=nsy if nsy<sy else sy
ex=nex if nex>ex else ex
ey=ney if ney>ey else ey
然后绘制边框:
bg=self['background'] if bg=='' else bg
frame=self.create_rectangle((sx-5,sy-20,ex+5,ey+5),fill=bg,outline=fg)
这里有一个细节,就是背景不建议在画布中透明,否则,当界面复杂时,很影响视觉效果。
标题
在TinUI中,并没有给LabelFrame的标题设置提供很多参数,至少目前是。
标题会被绘制在边框上方的正中间,同时绘制有一个矩形作为标题的背景。这个技巧在之前的几篇文章中都出现过很多次,这里直接上代码:
label=self.create_text(((sx+ex)//2,sy-20),font='微软雅黑 10',text=title,fill=fg,anchor='center')
self.create_rectangle(self.bbox(label),fill=bg,outline=bg)
self.tag_raise(label)
self.tag_lower(frame)
完整代码
def add_labelframe(self,widgets:tuple=(),title='',fg='#A8A8A8',bg=''):#绘制标题框
sx,sy,ex,ey=self.bbox(widgets[0])#获取直接的起始位置
for i in widgets:
nsx,nsy,nex,ney=self.bbox(i)
sx=nsx if nsx<sx else sx
sy=nsy if nsy<sy else sy
ex=nex if nex>ex else ex
ey=ney if ney>ey else ey
bg=self['background'] if bg=='' else bg
frame=self.create_rectangle((sx-5,sy-20,ex+5,ey+5),fill=bg,outline=fg)
label=self.create_text(((sx+ex)//2,sy-20),font='微软雅黑 10',text=title,fill=fg,anchor='center')
self.create_rectangle(self.bbox(label),fill=bg,outline=bg)
self.tag_raise(label)
self.tag_lower(frame)
return label,frame
效果
测试代码
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()
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 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),'测试按钮',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,300),350,30,'这里用来输入')
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/')
_,ok1=b.add_waitbar1((500,220),bg='lightgreen')
b.add_button((500,270),'停止等待动画',activefg='cyan',activebg='black',command=test2)
bu1=b.add_button((700,200),'nothing button 1')[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')
a.mainloop()
最终效果
github项目
pip下载
pip install tinui
结语
下一次将添加新的等待组件。
🔆tkinter创新🔆