TinEngine的tkinter标签
引言
TinEngine的tkinter标签,实际上就是<tkinter>标签。
格式上,该标签是一个多行参数标签,每一行的参数为TinText的控制代码,有开始标记和结束标记。
内容和作用上,该标签会单独读取每一个参数,并在每一个参数前加上“self.”,从而达到控制该TinText的效果。该标签的优先级低于所有容器标签,因此一般情况下,<tkinter>标签会一直执行Python代码,直到结束标记。
本篇文章,将详细讲述如何通过Tin标记语言的“tkinter”标签,实现简单到复杂的功能。
简单使用
接下来是用tkinter标签制作的一个功能:点击一个按钮,显示一个提示类的对话框。
<main>现在来实现一个通过<tkinter>完成的功能:在文本框中加入一个Button,点击Button后可以显示“hello”的对话框。
;开始标记为:<tkinter>
<tkinter>
window_create(self.end,window=ttk.Button(self,text="push me",command=lambda : showinfo("a info window","hello"))
update()
</tkinter>
;结束标记为:</tkinter>
这个功能十分简单。先确定使用tkinter文本框的window_create,然后载入一个ttk.Button,并且将按钮的触发事件绑定为一个通过lambda创建的匿名函数。这样,当按钮被点击时,就可以出现一个对话框了。
这是一个简单的功能,但要注意以下几点:
- “tkinter”标签的开始和结束标记必须要写
- 每一行的开头不需要加任何东西,直接使用TinText的函数
- TinEngine只解析每一行的tkinter代码,因此标签内每一行的代码将会单独运行
- 简单情况下,该标签内的变量为TinText自身环境的变量,与调用TinEngine的环境无关
从上面的几点注意,我们不难发现了几个重点,下面将详细解释。
tkinter 标签的注意内容
开头和结尾标记
Tin是标记语言,而且在“标记”这一方面做得比较彻底。表面上看可能跟HTML的元素块一样,但在解析模式上,Tin认的是状态而不是从属关系,因此这种多行标签必须要有开头和结尾标记。
直接使用函数&单行运行
在TinText的Python层面,基础代码是这样的:
#...
#tkinter_unit 是解析<tkinter>标签参数完后所有参数的列表
#类似:["update()","configure(foreground='black')","inset(self.end,'insert word')"]
for i in tkinter_unit:
py_code='self.'+i
exec(py_code)
因此,“tkinter”标签不支持多行代码,并且使用时,每一行的开头不需要加任何东西。
变量
在“如何用Python创造Tin”的系列文章中,明确讲述了TinText的渲染功能结构。TinText的渲染功能,在该类的函数:point_file()中,因此,关于底层(Python层面)的操作,所有的变量都应该是TinEngine的环境变量。
如果在你的程序中,这样使用Tin:
#import部分省略
def test():#自定义一个功能函数
showinfo("a info window","hello")
#下面的Tin标记中,使用绑定的代码不是匿名函数,而是本环境定义的test函数
word='''<tkinter>
window_create(self.end,window=ttk.Button(self,text="push me",command=test)
update()
</tkinter>
'''
root=Tk()
tin=TinText(root)
tin.pack(fill='both',expand=True)
tin.point_file(word.split('\n'))
root.mainloop()
然而,当你运行的时候,Tin会报错:不能存在“test”变量。
解决变量不通用的问题
这很好解决。
从结构上讲,“tkinter”标签中的变量,全部来自于TinEngine的环境变量,那么,我们只需要将自己程序中的函数,注册到TinText中即可。为了规范和方便使用,我们可以手动给定义TinText定义一个外部函数字典:
tin.func={}
#这里沿用上面的代码
tin.func['test']=test
然后,将Tin标记改为如下内容:
#下面的Tin标记中,使用绑定的代码不是匿名函数,而是本环境定义的test函数
word='''<tkinter>
window_create(self.end,window=ttk.Button(self,text="push me",command=self.func['test'])
update()
</tkinter>
'''
#将command执行TinText内部的变量
更改后的Tin标记能够正常运行。
结语
以上是对<tkinter>标签的使用十分简单的说明。
该标签完全能够完成更丰富的额外功能,下面给出TinGroup原生tins拓展中,linktitle2的标记文本:
<object>%题目%;%side%;%fg%;%bg%;%font%;%link%
;V2020年7月18日12:14:25
;link title 2
;对linktitle.tins的升级,融合onlywordtitle.tins,使TinReader只在标题文字处渲染背景色
<tkinter>
tag_configure('<owt>middle',justify='%side%')
insert('end',' ','<owt>middle')
</tkinter>
;只用onlywordtitle.tins中的技术
<tkinter>
tag_configure('<title>link>'+'%fg%'+'%bg%'+'%link%',foreground='%fg%',background='%bg%',justify='%side%',font=('%font%',size_dict['0']),relief='ridge',borderwidth=2,underline=True)
insert(self.end,'%题目%','<title>link>'+'%fg%'+'%bg%'+'%link%')#不同于<title>标签,该拓展标签不会自动换行
tag_bind('<title>link>'+'%fg%'+'%bg%'+'%link%','<Button-1>',lambda event:self.linkopen(event,'%link%'))
tag_bind('<title>link>'+'%fg%'+'%bg%'+'%link%','<Enter>',lambda event:self.show_hand_cursor(event,'%link%'))
tag_bind('<title>link>'+'%fg%'+'%bg%'+'%link%','<Leave>',lambda event:self.show_xterm_cursor(event))
</tkinter>
注意:TinEngine-V3(大概从TinReader-2.3.1-)开始,point_file接受完整的Tin标记文本,而不是行列表