前一篇文章tkinter-Text详解讲解的Text的一些基本属性和方法,本文会更深入一步,讲解mark
tag
image
window
,通过本文你将彻底弄懂这几个概念并能完全掌握它们的使用。废话不多说,干!
mark
顾名思义,mark就是标记。它标记啥呢?标记 文本中两个字符之间的位置(即两个字符间的空隙)。可以理解为mark用来"记忆"位置(position)信息。
注意:mark和字符没有关联,它仅和两个字符之间的间隔位置相关联。因为mark和字符无关,所以当mark邻近的字符被删除后,mark仍然有效。
mark_names()
获取当前所有的marks name
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
print(text.mark_names()) # 输出结果为('insert', 'current')
main_win.mainloop()
mark_set(markName, index)
添加自定义mark
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
text.mark_set('test_one', '1.4') # 在'1.4'位置处添加 名为'test_one'的mark
print(text.mark_names()) # 输出结果为('insert', 'current', 'test_one')
main_win.mainloop()
index(index)
前面我介绍过index。因为mark实际上也是代表了index信息,所有index()的参数index可以是自定义的mark.
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
text.mark_set('test_one', '1.4')
print(text.index('test_one')) # 1.4
print(text.index('current')) # 1.15
print(text.index('insert')) # 1.15
main_win.mainloop()
mark_gravity(markName, direction=None)
mark的graviry仅有两种’left’,‘right’,默认是’right’
‘left’ 表示 mark始终在新插入字符的左侧.例如,mark的位置是1.4,在mark处插入新的字符m,mark仍然在1.4处,也就是在字符’m’的左侧
‘right’ 表示 mark始终在新插入字符的右侧.例如,mark的位置是1.4,在markc处插入新的字符m,mark的位置变为1.5,也就是在字符’m’的右侧
如果没有指定direction,表示获取markname的gravity;如果指定了direction,表示设置markname的gravity.
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
text.mark_set('test_one', '1.4')
# 默认gravity为'right'
print(text.mark_gravity('test_one')) # 'right'
text.insert('test_one', 'm')
print(text.index('test_one') # 1.5
# 设置gravity为'left'
#text.mark_gravity('test_one', 'left')
#text.insert('test_one', 'm')
#print(text.index('test_one') # 1.4
main_win.mainloop()
mark_previous(index)
获取某个index之前的mark.
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
text.mark_set('test_one', '1.4')
# 获取'1.20'之前的markname
print(text.mark_previous('1.20')) # 输出结果为'test_one'
main_win.mainloop()
mark_unset(*markNames)
删除mark.
from tkinter import (Tk, Text)
from tkinter.constants import (RIGHT, LEFT, END, CURRENT)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao...')
text.mark_set('test_one', '1.4')
print(text.mark_names()) # ('insert', 'current', 'test_one')
text.mark_unset('test_one')
print(text.mark_names()) # ('insert', 'current')
main_win.mainloop()
tag
tag也是Text的一种标记,它用来将某个(些)文本区域关联起来,然后通过tag来独立控制这些关联区域的相关显示属性。
与mark的两点差异:
- tag是标记字符所在的索引,是与字符相关联,而不是与字符之间的空隙相关联。
- 如果tag标记的字符不存在了(被删除了),那么该tag与原先的字符索引区域的关联也随之消失。
tag_names(index=None)
Return a list of all tag names.
查看当前的有哪些tag。
tag_add(tagName, index1, *args)
Add tagName to all characters between index1 and index2 in ARGS.Additional pairs of indices may follow in ARGS.
根据tag_add函数的定义,可以知道,一个tag可以 关联一个字符、也可以关联一组字符、也可以关联多组字符。在编码层面就是通过index1及args参数来指定。
from tkinter import (Tk, Text)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao is a good blog to learn python.')
# 查看tag
print(text.tag_names()) # 输出 ('sel',)
text.tag_add('t1', '1.0', '1.4') # t1关联一组字符
text.tag_add('t2', '1.0', '1.4','1.7', '1.11') # t2关联两组字符
# 查看tag
print(text.tag_names()) # 输出 ('sel', 't1', 't2')
main_win.mainloop()
tag_configure(tagName, cnf=None, **kw)
也可以使用tag_config()函数
tag的第一个作用,设置显示属性就是通过tag_config函数来指定。
from tkinter import (Tk, Text)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao is a good blog to learn python.')
# 查看tag
print(text.tag_names()) # 输出 ('sel',)
text.tag_add('t1', '1.0', '1.4') # t1关联一组字符
text.tag_add('t2', '1.0', '1.4','1.7', '1.11') # t2关联两组字符
text.tag_add('t3', '1.13', '1.15') #t3关联一组字符
# 设置tag关联文本区域的显示属性
text.tag_config('t1', foreground='red', background='yellow')
text.tag_config('t2', foreground='blue', background='black')
text.tag_config('t3', elide=True)
# 查看tag
print(text.tag_names()) # 输出 ('sel', 't1', 't2', 't3')
main_win.mainloop()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxatqiuy-1594950344349)(tkinter_text_tag_config.png)]
第21行,设置了’t1’的前景为红色,背景为黄色
第22行,设置了’t2’的前景为蓝色,背景为黑色
第23行,设置了’t3’的文字隐藏,不显示
但是发现, 't1’关联的’hell’文本区域并不是显示为红字黄背景;'t2’关联的’yuda’文本区域显示为蓝字黑背景;'t3’关联的’is’隐藏不显示.
因为允许同一个字符或同一个文本区域可关联多个tag,那么就会存在到底用哪个tag设置的显示属性的问题.这就引出了tag优先级的概念。tag的优先级, 新定义的tag的优先级高于已定义的tag的优先级。也就是说,'t2’的优先级高于’t1’的优先级,1.0-1.4区域的文本将显示蓝色黑背景而不是红色黄背景。
如果仅通过tag_add()的调用顺序来决定tag的优先级,在实际使用时,会非常的难受。当然需要能动态设置tag的优先级。
tag_raise(tagName, aboveThis=None)
提高tagName的优先级。若没有指定aboveThis,则将tagName的优先级提高到最高;若指定aboveThis,则将tagName的优先级设置为高于aboveThis。
tag_lower(tagName, belowThis=None)
降低tagName的优先级。若没有指定belowThis,则将tagName的优先级降低到最低;若指定belowThis,则将tagName的优先级设置为低于belowThis。
from tkinter import (Tk, Text)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao is a good blog to learn python.')
# 查看tag
print(text.tag_names()) # 输出 ('sel',)
text.tag_add('t1', '1.0', '1.4') # t1关联一组字符
text.tag_add('t2', '1.0', '1.4','1.7', '1.11') # t2关联两组字符
text.tag_add('t3', '1.13', '1.15') #t3关联一组字符
# 设置tag关联文本区域的显示属性
text.tag_config('t1', foreground='red', background='yellow')
text.tag_config('t2', foreground='blue', background='black')
text.tag_config('t3', elide=True)
text.tag_raise('t1') # 将't1'的优先级提高到最高
print(text.tag_names()) # 输出 ('sel', 't2', 't3', 't1')
#text.tag_lower('t2') # 将't2'的优先级降低到最低
#print(text.tag_names()) # 输出 ('t2', 'sel', 't3', 't1')
#text.tag_raise('t1', aboveThis='t2') # 将't1'的优先级提高到't2'之上
#print(text.tag_names()) # 输出 ('sel', 't2', 't1', 't3')
main_win.mainloop()
tag_delete(*tagNames)
删除一个或多个tagName。
from tkinter import (Tk, Text)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert(CURRENT, 'hello, yudao is a good blog to learn python.')
# 查看tag
print(text.tag_names()) # 输出 ('sel',)
text.tag_add('t1', '1.0', '1.4') # t1关联一组字符
text.tag_add('t2', '1.0', '1.4','1.7', '1.11') # t2关联两组字符
text.tag_add('t3', '1.13', '1.15') #t3关联一组字符
# 设置tag关联文本区域的显示属性
text.tag_config('t1', foreground='red', background='yellow')
text.tag_config('t2', foreground='blue', background='black')
text.tag_config('t3', elide=True)
text.tag_delete('t3')
print(text.tag_names()) # 输出为('sel', 't1', 't2')
main_win.mainloop()
tag_cget(tagName, option)
获取tagName的某个属性(option)值。
print(text.tag_cget('t1', 'background')) # 输出yellow
tag_ranges(tagName)
获取tagName的文本区域范围, 如’t1’的文本区域范围是1.0-1.4。
print(text.tag_ranges('t1'))
#(<string object: '1.0'>, <string object: '1.4'>)
print(text.tag_ranges('t2'))
#(<string object: '1.0'>, <string object: '1.4'>, <string object: '1.7'>, <string object: '1.11'>)
print(text.tag_ranges('t3'))
#(<string object: '1.13'>, <string object: '1.15'>)
tag_remove(tagName, index1, index2=None)
移除与tagName关联的文本区域[index1, index2)。
text.tag_remove('t2', '1.0', '1.4')
print(text.tag_ranges('t1'))
#(<string object: '1.0'>, <string object: '1.4'>)
print(text.tag_ranges('t2'))
#(<string object: '1.7'>, <string object: '1.11'>)
print(text.tag_ranges('t3'))
#(<string object: '1.13'>, <string object: '1.15'>)
image
前面介绍了Text的 index,mark,tag;可以理解为对Text插入一些不同种类的"标签"。既然能插入"标签",那么能不能插入图片呢?我来试试。
image_create(index, cnf={}, **kw)
在index处插入一张image。image_create的返回值是字符串(image name),image name由tkinter自动分配。
from tkinter import (Tk, Text, PhotoImage)
main_win = Tk()
main_win.title('渔道的Text控件')
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
tubiao = PhotoImage(file='tubiao.png')
tt = text.image_create('1.0', image=tubiao)
print(tt) #输出image name为 pyimage1
main_win.mainloop()
可以看出,在Text文本框中插入了一张图标,tt为"pyimage1"
image_names()
获取Text对象所有嵌入其中的image name
print(text.image_names()) #输出为 ('pyimage1',)
image_cget(index, option)
获取在index
处嵌入的图像的属性值
tubiao = PhotoImage(file='tubiao.png')
tt = text.image_create('1.0', image=tubiao)
image1 = text.image_cget('1.0', 'image')
print(f'image>>>{image1}')# 输出image>>>pyimage1
name1 = text.image_cget('1.0', 'name')
print(f'name>>>{name1}') # 输出name>>>
image_configure(index, cnf=None, **kw)
给index
处嵌入的图像设置属性
image1 = text.image_cget('1.0', 'image')
print(f'image>>>{image1}')# 输出 image>>>pyimage1
name1 = text.image_cget('1.0', 'name')
print(f'name>>>{name1}')# 输出 name>>>
text.image_configure('1.0', name='tubiao')
print(f"image>>>{text.image_cget('1.0', 'image')}") #输出 image>>>pyimage1
print(f"name>>>{text.image_cget('1.0', 'name')}") #输出 name>>>tubiao
第6行设置了image的name属性的值为’tubiao’,第9行获取该image的name属性值。
通过前面对Text中image相关方法的介绍,我可以基于这些方法来进行组合,完成更多可能性。
例如,同一个Text对象中嵌入多个图片;同一个图片对象嵌入到Text的多个不同index。
from tkinter import (Tk, Text, PhotoImage)
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
tubiao = PhotoImage(file='tubiao.png')
tt = text.image_create('1.0', image=tubiao)# 在'1.0'处插入'tubiao.png'
tubiao2 = PhotoImage(file='tubiao2.png')
tt2 = text.image_create('1.1', image=tubiao2)# 在'1.1'处插入'tubiao2.png'
text.image_cget('1.1', 'image')
main_win.mainloop()
from tkinter import (Tk, Text, PhotoImage)
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
tubiao = PhotoImage(file='tubiao.png')
tt = text.image_create('1.0', image=tubiao)# 在'1.0'处插入'tubiao.png'
tt2 = text.image_create('1.1', image=tubiao)
tt2 = text.image_create('1.2', image=tubiao)
tt2 = text.image_create('1.3', image=tubiao)
main_win.mainloop()
Text控件中除了可以嵌入图片外,还可以嵌入其他控件。在tkinter中控件widget都是window。
window
window_create(index, cnf={}, **kw)
创建待嵌入window对象
window_names()
获取已嵌入window对象
window_configure(index, cnf=None, **kw)
配置嵌入window的属性
window_cget(index, option)
获取index
处已嵌入window的属性
from tkinter import (Tk, Text, PhotoImage)
width = 300
height = 300
main_win.geometry(f'{width}x{height}')
text = Text(main_win, width=40, height=10)
text.pack()
text.insert('insert', '我是')
bt1 = Button(text,text='渔道')
text.window_create(CURRENT, window=bt1)
print(text.window_names())# ('.!text.!button',)
main_win.mainloop()
以上就是我对mark
tag
image
window
的理解,如果你有更好的见解,欢迎讨论。