标记文本小部件中的字符会减慢程序速度
Tokenizing the characters in text widget slows the program
当我将一些python脚本的内容插入文本小部件时,内容可以快速突出显示。同样在插入内容后,也可以突出显示手动键入的新插入内容。但是,在将一些 python 脚本的内容插入到文本小部件后,新插入的内容 插入速度很快,但突出显示有延迟 。
我应该怎么做才能解决这个问题?
提前致谢。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
exit()
elif sys.version_info.major == 3:
import io
import keyword
import builtins
import tokenize
import threading
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root, fg="white", bg="black", font="TkDefaultFont 10")
text.pack(fill="both", expand=True)
count = 0
def colorize(*args):
global count
row1, col1 = args[0].start
start = str(row1) + "." + str(col1)
row2, col2 = args[0].end
end = str(row2) + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
def search():
while True:
try:
for i in tokenize.tokenize(io.BytesIO(text.get("1.0", "end").encode("utf-8")).readline):
if i.type == 1:
if i.string in keyword.kwlist:
colorize(i, "orange")
elif i.string in dir(builtins):
colorize(i, "blue")
else:
colorize(i, "white")
elif i.type == 2:
colorize(i, "cyan")
elif i.type == 3:
colorize(i, "purple")
elif i.type == 53:
if i.string == "," or i.string == "." or i.string == ":":
colorize(i, "orange")
elif i.string == "(" or i.string == ")" or i.string == "[" \
or i.string == "]" or i.string == "{" or i.string == "}":
colorize(i, "darkred")
else:
colorize(i, "green")
elif i.type == 57:
colorize(i, "grey", "TkDefaultFont 10 italic")
except tokenize.TokenError:
pass
thread = threading.Thread(target=search)
thread.daemon = True
thread.start()
thread.join(1)
root.mainloop()
问题已解决。
线程模块已从代码中删除。现在,解析操作是通过键绑定 ("<KeyRelease>"
) 完成的。因此,search()
函数中的 while 循环也被删除了。
colorize(*args)
函数更改为:
def colorize(*args):
global count
row = text.index("insert").split(".")[0]
col1 = args[0].start[-1]
start = row + "." + str(col1)
col2 = args[0].end[-1]
end = row + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
根据这个函数,行变量设置为插入位置,停止重复着色整个内容。所以只有最后一行需要扫描和着色。
针对不同的情况定义了两种解析方法。
当插入位置在最后一行时,第一个解析器被激活。第一个解析器在我之前的 post 的 search()
方法之间的核心没有改变。当想要将复制的代码粘贴到小部件中时,将激活第二个解析器。
这是第二种解析器方法:
keysym = set()
def parser_2(*args):
global keysym
keysym = set()
for i in range(int(args[0])):
text.mark_set("insert", "{}.{}".format(i + 1, args[1]))
parser_1(text.get("{}.0".format(i + 1), "{}.0".format(i + 2)))
text.mark_set("insert", "{}.{}".format(args[0], args[1]))
将复制的代码插入到小部件后,插入位置发生了预期变化。因此,如果我们在 for 循环中直接 或反向 访问所有行,并设置所有这些已访问行的标记,然后使用参数调用 parser_1(*args)
函数( arguments 是访问插入位置的行和列) 然后重新设置标记到正常插入位置,复制的内容可以着色一次。这是用户键入ctrl+v或用户想使用右键菜单将代码粘贴到widget时的着色快捷功能。
最后一个函数(select_parser(event)
)是根据不同的情况选择解析器。
def select_parser(event):
row, col = text.index("insert").split(".")
if event.keysym == "Control_L":
keysym.add(event.keysym)
elif event.keysym == "v" or event.keysym == "V":
keysym.add(event.keysym)
if "Control_L" in keysym:
parser_2(row, col)
elif event.keysym == "Control_R":
keysym.add(event.keysym)
if "v" in keysym or "V" in keysym:
parser_2(row, col)
else:
parser_1(text.get("{}.0".format(row), "{}.0".format(int(row) + 1)))
一种情况是当用户键入 "Control_L" 时。如果用户键入它,它会被添加到全局定义的 keysym 集中。
另一种情况是用户输入"v"或"V"。如果用户键入其中之一,event.keysym
也会添加到 keysym 集中。在这种情况下定义了一个不同的条件,用于检查 "Control_L" 是否在 keysym 集合中。如果在,则调用第二个解析方法。 keysym 在第二个解析器方法中被重新定义。
另一种情况是用户输入"Control_R"。如果用户键入它,它也会被添加到 keysym 集中。这里定义了另一个条件,检查 "v" 或 "V" 是否在 keysym设置与否。 (当我们键入"Control_R + v"时,首先将"v"添加到keysym设置但是当我们键入 "Control_L + v" 时,首先 "Control_L" 被添加到 keysym set.) 如果 "v" 或者 "V" 在 keysym set ,调用第二个解析方法。 keysym 在第二个解析器方法中被重新定义。
最后一种情况是用户键入的键与上述键不同。在这种情况下,第一个解析器方法被调用。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
exit()
elif sys.version_info.major == 3:
import io
import keyword
import builtins
import tokenize
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root, fg="white", bg="black", font="TkDefaultFont 10")
text.pack(fill="both", expand=True)
count = 0
def colorize(*args):
global count
row = text.index("insert").split(".")[0]
col1 = args[0].start[-1]
start = row + "." + str(col1)
col2 = args[0].end[-1]
end = row + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
def parser_1(*args):
try:
for i in tokenize.tokenize(io.BytesIO(
args[0].encode("utf-8")).readline):
if i.type == 1:
if i.string in keyword.kwlist:
colorize(i, "orange")
elif i.string in dir(builtins):
colorize(i, "blue")
else:
colorize(i, "white")
elif i.type == 2:
colorize(i, "cyan")
elif i.type == 3:
colorize(i, "purple")
elif i.type == 53:
if i.string == "," or i.string == "." or i.string == ":":
colorize(i, "orange")
elif i.string == "(" or i.string == ")" or i.string == "[" \
or i.string == "]" or i.string == "{" or i.string == "}":
colorize(i, "darkred")
else:
colorize(i, "green")
elif i.type == 57:
colorize(i, "grey", "TkDefaultFont 10 italic")
except tokenize.TokenError:
pass
keysym = set()
def parser_2(*args):
global keysym
keysym = set()
for i in range(int(args[0])):
text.mark_set("insert", "{}.{}".format(i + 1, args[1]))
parser_1(text.get("{}.0".format(i + 1), "{}.0".format(i + 2)))
text.mark_set("insert", "{}.{}".format(args[0], args[1]))
def select_parser(event):
row, col = text.index("insert").split(".")
if event.keysym == "Control_L":
keysym.add(event.keysym)
elif event.keysym == "v" or event.keysym == "V":
keysym.add(event.keysym)
if "Control_L" in keysym:
parser_2(row, col)
elif event.keysym == "Control_R":
keysym.add(event.keysym)
if "v" in keysym or "V" in keysym:
parser_2(row, col)
else:
parser_1(text.get("{}.0".format(row), "{}.0".format(int(row) + 1)))
text.bind("<KeyRelease>", select_parser)
root.mainloop()
当我将一些python脚本的内容插入文本小部件时,内容可以快速突出显示。同样在插入内容后,也可以突出显示手动键入的新插入内容。但是,在将一些 python 脚本的内容插入到文本小部件后,新插入的内容 插入速度很快,但突出显示有延迟 。
我应该怎么做才能解决这个问题?
提前致谢。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
exit()
elif sys.version_info.major == 3:
import io
import keyword
import builtins
import tokenize
import threading
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root, fg="white", bg="black", font="TkDefaultFont 10")
text.pack(fill="both", expand=True)
count = 0
def colorize(*args):
global count
row1, col1 = args[0].start
start = str(row1) + "." + str(col1)
row2, col2 = args[0].end
end = str(row2) + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
def search():
while True:
try:
for i in tokenize.tokenize(io.BytesIO(text.get("1.0", "end").encode("utf-8")).readline):
if i.type == 1:
if i.string in keyword.kwlist:
colorize(i, "orange")
elif i.string in dir(builtins):
colorize(i, "blue")
else:
colorize(i, "white")
elif i.type == 2:
colorize(i, "cyan")
elif i.type == 3:
colorize(i, "purple")
elif i.type == 53:
if i.string == "," or i.string == "." or i.string == ":":
colorize(i, "orange")
elif i.string == "(" or i.string == ")" or i.string == "[" \
or i.string == "]" or i.string == "{" or i.string == "}":
colorize(i, "darkred")
else:
colorize(i, "green")
elif i.type == 57:
colorize(i, "grey", "TkDefaultFont 10 italic")
except tokenize.TokenError:
pass
thread = threading.Thread(target=search)
thread.daemon = True
thread.start()
thread.join(1)
root.mainloop()
问题已解决。
线程模块已从代码中删除。现在,解析操作是通过键绑定 ("<KeyRelease>"
) 完成的。因此,search()
函数中的 while 循环也被删除了。
colorize(*args)
函数更改为:
def colorize(*args):
global count
row = text.index("insert").split(".")[0]
col1 = args[0].start[-1]
start = row + "." + str(col1)
col2 = args[0].end[-1]
end = row + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
根据这个函数,行变量设置为插入位置,停止重复着色整个内容。所以只有最后一行需要扫描和着色。
针对不同的情况定义了两种解析方法。
当插入位置在最后一行时,第一个解析器被激活。第一个解析器在我之前的 post 的 search()
方法之间的核心没有改变。当想要将复制的代码粘贴到小部件中时,将激活第二个解析器。
这是第二种解析器方法:
keysym = set()
def parser_2(*args):
global keysym
keysym = set()
for i in range(int(args[0])):
text.mark_set("insert", "{}.{}".format(i + 1, args[1]))
parser_1(text.get("{}.0".format(i + 1), "{}.0".format(i + 2)))
text.mark_set("insert", "{}.{}".format(args[0], args[1]))
将复制的代码插入到小部件后,插入位置发生了预期变化。因此,如果我们在 for 循环中直接 或反向 访问所有行,并设置所有这些已访问行的标记,然后使用参数调用 parser_1(*args)
函数( arguments 是访问插入位置的行和列) 然后重新设置标记到正常插入位置,复制的内容可以着色一次。这是用户键入ctrl+v或用户想使用右键菜单将代码粘贴到widget时的着色快捷功能。
最后一个函数(select_parser(event)
)是根据不同的情况选择解析器。
def select_parser(event):
row, col = text.index("insert").split(".")
if event.keysym == "Control_L":
keysym.add(event.keysym)
elif event.keysym == "v" or event.keysym == "V":
keysym.add(event.keysym)
if "Control_L" in keysym:
parser_2(row, col)
elif event.keysym == "Control_R":
keysym.add(event.keysym)
if "v" in keysym or "V" in keysym:
parser_2(row, col)
else:
parser_1(text.get("{}.0".format(row), "{}.0".format(int(row) + 1)))
一种情况是当用户键入 "Control_L" 时。如果用户键入它,它会被添加到全局定义的 keysym 集中。
另一种情况是用户输入"v"或"V"。如果用户键入其中之一,event.keysym
也会添加到 keysym 集中。在这种情况下定义了一个不同的条件,用于检查 "Control_L" 是否在 keysym 集合中。如果在,则调用第二个解析方法。 keysym 在第二个解析器方法中被重新定义。
另一种情况是用户输入"Control_R"。如果用户键入它,它也会被添加到 keysym 集中。这里定义了另一个条件,检查 "v" 或 "V" 是否在 keysym设置与否。 (当我们键入"Control_R + v"时,首先将"v"添加到keysym设置但是当我们键入 "Control_L + v" 时,首先 "Control_L" 被添加到 keysym set.) 如果 "v" 或者 "V" 在 keysym set ,调用第二个解析方法。 keysym 在第二个解析器方法中被重新定义。
最后一种情况是用户键入的键与上述键不同。在这种情况下,第一个解析器方法被调用。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
exit()
elif sys.version_info.major == 3:
import io
import keyword
import builtins
import tokenize
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root, fg="white", bg="black", font="TkDefaultFont 10")
text.pack(fill="both", expand=True)
count = 0
def colorize(*args):
global count
row = text.index("insert").split(".")[0]
col1 = args[0].start[-1]
start = row + "." + str(col1)
col2 = args[0].end[-1]
end = row + "." + str(col2)
text.tag_add(str(count), start, end)
try:
text.tag_config(str(count), foreground=args[1], font=args[2])
except IndexError:
text.tag_config(str(count), foreground=args[1])
count += 1
def parser_1(*args):
try:
for i in tokenize.tokenize(io.BytesIO(
args[0].encode("utf-8")).readline):
if i.type == 1:
if i.string in keyword.kwlist:
colorize(i, "orange")
elif i.string in dir(builtins):
colorize(i, "blue")
else:
colorize(i, "white")
elif i.type == 2:
colorize(i, "cyan")
elif i.type == 3:
colorize(i, "purple")
elif i.type == 53:
if i.string == "," or i.string == "." or i.string == ":":
colorize(i, "orange")
elif i.string == "(" or i.string == ")" or i.string == "[" \
or i.string == "]" or i.string == "{" or i.string == "}":
colorize(i, "darkred")
else:
colorize(i, "green")
elif i.type == 57:
colorize(i, "grey", "TkDefaultFont 10 italic")
except tokenize.TokenError:
pass
keysym = set()
def parser_2(*args):
global keysym
keysym = set()
for i in range(int(args[0])):
text.mark_set("insert", "{}.{}".format(i + 1, args[1]))
parser_1(text.get("{}.0".format(i + 1), "{}.0".format(i + 2)))
text.mark_set("insert", "{}.{}".format(args[0], args[1]))
def select_parser(event):
row, col = text.index("insert").split(".")
if event.keysym == "Control_L":
keysym.add(event.keysym)
elif event.keysym == "v" or event.keysym == "V":
keysym.add(event.keysym)
if "Control_L" in keysym:
parser_2(row, col)
elif event.keysym == "Control_R":
keysym.add(event.keysym)
if "v" in keysym or "V" in keysym:
parser_2(row, col)
else:
parser_1(text.get("{}.0".format(row), "{}.0".format(int(row) + 1)))
text.bind("<KeyRelease>", select_parser)
root.mainloop()