我得到了一段代码,可以使用 Tkinter Text Widget 突出显示 Python 的语法。但是,我仍然无法突出显示“def”之后的函数名和“class”之后的类名以及“import”之后的包名。如果缺少明显的东西,请温柔地将信息传达给我。
python.yaml
categories:
keywords:
color: orange
matches: ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
variables:
color: red4
matches: ['True', 'False', None]
functions:
color: "#525fe9"
matches: ['abs',delattr','hash','memoryview','set','all','dict','help','min','setattr','any','dir','hex','next','slice','ascii','divmod','id','object','sorted','bin','enumerate','input','oct','staticmethod','bool','eval','int','open','str','breakpoint','exec','isinstance','ord','sum','bytearray','filter','issubclass','pow','super','bytes','float','iter','print','tuple','callable','format','len','property','type','chr','frozenset','list','range','vars','classmethod','getattr','locals','repr','zip','compile','globals','map','reversed','__import__','complex','hasattr','max',round']
numbers:
color: pink
strings:
color: "#e16d5b"
highlighter.py 有助于突出显示它从 python.yaml 文件中获取的单词。
import tkinter as tk
import yaml
class Highlighter:
def __init__(self, text_widget, syntax_file):
self.text_widget = text_widget
self.syntax_file = syntax_file
self.categories = None
self.numbers_color = "blue"
self.disallowed_previous_chars = ["_", "-", "."]
self.parse_syntax_file()
self.text_widget.bind('<KeyRelease>', self.on_key_release)
def on_key_release(self, event=None):
self.highlight()
def parse_syntax_file(self):
with open(self.syntax_file, 'r') as stream:
config = yaml.safe_load(stream)
self.categories = config['categories']
self.numbers_color = config['numbers']['color']
self.strings_color = config['strings']['color']
self.configure_tags()
def callback_1(self,event):
info_window = tk.Tk()
info_window.overrideredirect(1)
info_window.geometry("200x24+{0}+{1}".format(event.x_root-100, event.y_root-12))
label = tk.Label(info_window, text="Word definition goes here.")
label.pack(fill=tk.BOTH)
info_window.bind_all("<Leave>", lambda e: info_window.destroy()) # Remove popup when pointer leaves the window
info_window.mainloop()
def configure_tags(self):
for category in self.categories.keys():
color = self.categories[category]['color']
self.text_widget.tag_configure(category, foreground=color)
self.text_widget.tag_configure("number", foreground=self.numbers_color)
self.text_widget.tag_configure("string", foreground=self.strings_color)
self.text_widget.tag_bind("string","<Enter>", self.callback_1)
def highlight(self, event=None):
length = tk.IntVar()
for category in self.categories:
matches = self.categories[category]['matches']
for keyword in matches:
start = 1.0
keyword = keyword + "[^A-Za-z_-]"
idx = self.text_widget.search(keyword, start, stopindex=tk.END, count=length, regexp=1)
while idx:
char_match_found = int(str(idx).split('.')[1])
line_match_found = int(str(idx).split('.')[0])
if char_match_found > 0:
previous_char_index = str(line_match_found) + '.' + str(char_match_found - 1)
previous_char = self.text_widget.get(previous_char_index, previous_char_index + "+1c")
if previous_char.isalnum() or previous_char in self.disallowed_previous_chars:
end = f"{idx}+{length.get() - 1}c"
start = end
idx = self.text_widget.search(keyword, start, stopindex=tk.END, regexp=1)
else:
end = f"{idx}+{length.get() - 1}c"
self.text_widget.tag_add(category, idx, end)
start = end
idx = self.text_widget.search(keyword, start, stopindex=tk.END, regexp=1)
else:
end = f"{idx}+{length.get() - 1}c"
self.text_widget.tag_add(category, idx, end)
start = end
idx = self.text_widget.search(keyword, start, stopindex=tk.END, regexp=1)
self.highlight_regex(r"(\d)+[.]?(\d)*", "number")
self.highlight_regex(r"[\'][^\']*[\']", "string")
self.highlight_regex(r"[\"][^\']*[\"]", "string")
def highlight_regex(self, regex, tag):
length = tk.IntVar()
start = 1.0
idx = self.text_widget.search(regex, start, stopindex=tk.END, regexp=1, count=length)
while idx:
end = f"{idx}+{length.get()}c"
self.text_widget.tag_add(tag, idx, end)
self.text_widget.tag_bind("string","<Enter>", self.callback_1)
start = end
idx = self.text_widget.search(regex, start, stopindex=tk.END, regexp=1, count=length)
if __name__ == '__main__':
w = tk.Tk()
x=tk.Text(w)
x.pack(fill=tk.BOTH,expand=1)
h = Highlighter(x, 'Path/to/python.yaml')
w.mainloop()