在TinUI带状等待框这一篇文章中,我提到了TinUI的20号组件。但是有人提问了,第二篇刷新滚动范围也算是组件吗?那当然不是,看完这一篇文章就知道了。
TinUI截止目前(2022年2月5日)确实有20个组件,其中就有本篇的主角,超链接,我也不知道之前为什么没写。但是介于之前已经有了这个组件,我就加上了“bleem”编号。
超链接的作用不言而喻,经过几次样式更改后,最终确定了WinUI3风格的超链接。当然,这都是在link组件已经完成之后的更改。
为什么使用“bleem”编号,这是因为“bleem”是介于3和4之间的整数。不要问为什么,最近看了一部电影。
def add_link(self,pos:tuple,text,url:Union[str,FunctionType],fg='#4f62ca',activefg='red',activebg='#eaeaea',font:tuple=('微软雅黑',12),anchor='nw'):#绘制超链接
'''
pos::其实位置
text::文本
url::指向的链接或函数
fg::字体颜色
activefg::响应鼠标字体颜色
activebg::响应鼠标背景颜色
font::字体
anchor::对齐方向
'''
有意思的是,url
参数允许str
类和function
类,这就代表了这不仅是超链接,还可以是作为窗口界面与界面之间的内部链接。
如果在之前写这一篇文章,我一定会详细说明tkinter画布绘制控件的过程,但现在这么多篇了,我就直接给代码了:
link=self.create_text(pos,text=text,fill=fg,font=font,anchor=anchor)
uid='link'+str(link)
self.itemconfig(link,tags=uid)
font=self.itemcget(link,'font')+' underline'
self.itemconfig(link,font=font)
bbox=self.bbox(link)
back=self.create_rectangle((bbox[0]-2,bbox[1]-2,bbox[2]+2,bbox[3]+2),width=0,tags=uid)
self.tkraise(link)
因为link需要响应鼠标进出事件,而且还需要绑定点击事件,因此我们需要为文本和背景分别绑定各自的事件函数。
self.tag_bind(link,'' ,turn_red)
self.tag_bind(link,'' ,turn_back)
self.tag_bind(link,'' ,go_url)
self.tag_bind(back,'' ,turn_red)
self.tag_bind(back,'' ,turn_back)
self.tag_bind(back,'' ,go_url)
鼠标进入:
def turn_red(event):
self.itemconfig(link,fill=activefg)
self.itemconfig(back,fill=activebg)
self['cursor']='hand2'
鼠标离开:
def turn_back(event):
self.itemconfig(link,fill=fg)
self.itemconfig(back,fill='')
self['cursor']='arrow'
此刻,我们还需要判断参数url
是什么东东就可以完成组件绘制了。
我也不知道为何,Python内置函数中没有function
。可能是因为和str
, int
, list
等内置参数相比,Python不允许直接使用函数来创建函数。因此,我使用的是types
中的FunctionType
来表示函数类,但是鼠标点击的函数中没有使用,而在参数限制类中起作用。
def go_url(event):
#如果是字符串,则打开网页;是方法,则执行函数
if type(url)==str:
webopen(url)
else:
url(event)
def add_link(self,pos:tuple,text,url:Union[str,FunctionType],fg='#4f62ca',activefg='red',activebg='#eaeaea',font:tuple=('微软雅黑',12),anchor='nw'):#绘制超链接
def turn_red(event):
self.itemconfig(link,fill=activefg)
self.itemconfig(back,fill=activebg)
self['cursor']='hand2'
def turn_back(event):
self.itemconfig(link,fill=fg)
self.itemconfig(back,fill='')
self['cursor']='arrow'
def go_url(event):
#如果是字符串,则打开网页;是方法,则执行函数
if type(url)==str:
webopen(url)
else:
url(event)
def disable(fg='#b0b0b0'):
self.itemconfig(link,state='disable',fill=fg)
self.itemconfig(back,state='disable')
def active():
self.itemconfig(link,state='normal',fill=fg)
self.itemconfig(back,state='normal')
link=self.create_text(pos,text=text,fill=fg,font=font,anchor=anchor)
uid='link'+str(link)
self.itemconfig(link,tags=uid)
font=self.itemcget(link,'font')+' underline'
self.itemconfig(link,font=font)
bbox=self.bbox(link)
back=self.create_rectangle((bbox[0]-2,bbox[1]-2,bbox[2]+2,bbox[3]+2),width=0,tags=uid)
self.tkraise(link)
self.tag_bind(link,'' ,turn_red)
self.tag_bind(link,'' ,turn_back)
self.tag_bind(link,'' ,go_url)
self.tag_bind(back,'' ,turn_red)
self.tag_bind(back,'' ,turn_back)
self.tag_bind(back,'' ,go_url)
funcs=[disable,active]
return link,funcs,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 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已可应用于项目。''',
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,'这里用来输入')
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())
b.add_textbox((890,100),text='这是文本输入框')
a.mainloop()
command
,优先级高于url,接受url
参数如果参数为超链接,则显示网址(保证安全,最近看了一下WinUI3发现大事不妙)。
TinUI的github项目地址
pip install tinui
TinUI推出了最新的现代化xml布局方式——TinUIXml。赶快去使用吧!!!
tkinter创新