转-tkinter-15-text-2

References

判断内容是否发生变化

比如说做一个笔记本(.txt的那个记事本)程序,或者重新做一个IDLE。它们都有输入框,有输入框当程序在关闭的时候应该自动检测内容是否发生改变,如果有改变但用户并没有保存的时候,应该提醒用户是否保存。

我们这个例子是通过验证文本的md5摘要来判断文本是否发生改变。

from tkinter import *  
import hashlib  #获得md5的值要用该库  
  
root = Tk()  
  
text = Text(root, width=30, height=5)  
text.pack()  
  
text.insert(INSERT, 'I love study')  
contents = text.get('1.0', END)  
  
def getSig(contents):  
    n = hashlib.md5(contents.encode())  
    return n.digest()  #只需要得到md5值n的简单摘要即可  
  
sig = getSig(contents)  
  
def check():  #点下检查的时候,会重新获得一次contents的内容,将原来的contents进行一个md5的hash,获得它的md5的值;同时也获得之后contents的md5的值,将两者进行对比。由于一个内容只能产生一个唯一的散列,因此若不一样,就说明内容发生了改变。  
    contents = text.get('1.0', END)  
    if sig != getSig(contents):  
        print("内容发生变动")  
    else:  
        print("内容没有发生变动")  
  
Button(root, text="检查", command=check).pack()  
  
mainloop()  

给Text中的文字添加链接

from tkinter import *
import webbrowser

root = Tk()

text = Text(root, width=30, height=5)
text.pack()

text.insert(INSERT, "I love FishC.com!")

text.tag_add("link", "1.7", "1.16")
text.tag_config("link", foreground="blue", underline=True)

def show_arrow_cursor(event):
    text.config(cursor="arrow")

def show_xterm_cursor(event):
    text.config(cursor="xterm")

def click(event):
    webbrowser.open("http://www.fishc.com")

text.tag_bind("link", "<Enter>", show_arrow_cursor)
text.tag_bind("link", "<Leave>", show_xterm_cursor)
text.tag_bind("link", "<Button-1>", click)

mainloop()

查找操作

查找使用search方法,使用search方法可以对text的内容进行搜索。不过默认是只找到第一个位置。下面是一个可以全文搜索的例子:

from tkinter import *  
import hashlib  #获得md5的值要用该库  
  
root = Tk()  
  
text = Text(root, width=30, height=5)  
text.pack()  
  
text.insert(INSERT, 'I enjoy studying Python')  
  
def getIndex(text, index):   #要把任何支持的格式转化为默认行列字符串的格式可以使用Text组件的index()方法  
    return tuple(map(int, str.split(text.index(index), '.')))  #将转化好的转化成一个元组的形式返回  
  
start = '1.0'  
while True:  
    pos = text.search("y", start, stopindex=END)  
    if not pos:  #找不到就跳出循环  
        break  
    print("找到了,位置是:", getIndex(text, pos)) #把找到的位置转化为人类能读懂的位置  
    start = pos + '+1c'  #将start的位置指向下一个字符  
      
mainloop() 

Text组件恢复和撤销的操作

我们可以简单设置Text组件的undo选项为True开启其撤销功能,然后使用edit_undo()方法来实现撤销操作,用edit_redo()的方法来实现其恢复操作。

from tkinter import *  
  
root = Tk()  
  
text = Text(root, width=30, height=5, undo=True)  
text.pack()  
  
text.insert(INSERT, 'I enjoy studying Python')  
  
def show():  
    text.edit_undo()  
  
Button(root, text='撤销', command=show).pack()  
  
mainloop() 

这是因为Text组件内部有一个栈专门用于记录内容的每次变动,所以每次撤销操作就是一次弹栈操作,恢复就是再次压栈。

默认情况下,每一次完整操作将会放入栈中但怎么样才算是一次完整的操作呢?Tkinter觉得每次焦点切换,用户按下Enter键。删除\插入操作的转换等之前的操作算是一次完整的操作。

那我们能不能自定义呢?比如说我希望插入一个字符就算一次完整的操作,然后每次点击撤销就去掉一个字符。

当然可以,做法就是先将autoseparators选项设置为False(因为这个选项是让Tkinter在认为一次完整的操作结束后自动插入“分隔符”),然后绑定键盘事件,每次有输入就用edit_separator()方法人为地插入一个“分隔符”:

from tkinter import *  
  
root = Tk()  
  
text = Text(root, width=30, height=5, undo=True, autoseparators=False)  
text.pack()  
  
text.insert(INSERT, 'I enjoy studying Python')  
  
def callback(event):  
    text.edit_separator()  
  
text.bind('<Key>', callback)  #一旦有键盘事件就人为地插入一个分隔符  
  
def show():  
    text.edit_undo()  
  
Button(root, text='撤销', command=show).pack()  
  
mainloop() 
Table of Contents