如何使用Pygments在Tkinter的Text控件中实现Python语法高亮
基于Pygments实现Tkinter Text组件Python语法高亮方案
前置依赖
先安装Pygments库:
pip install pygments
实现逻辑
- 利用Pygments内置的
PythonLexer对文本内容做词法解析,拆分出关键字、注释、字符串、数字等不同语法单元 - 为Tkinter Text组件预注册不同语法单元对应的样式标签,自定义颜色、字体样式
- 绑定文本框的键盘输入事件,内容更新时先清空原有高亮标签,再根据解析结果为对应文本区间添加样式标签
完整可运行代码
import tkinter as tk from pygments.lexers import PythonLexer from pygments.token import Token # 语法高亮样式配置,可根据需求自定义颜色、字体样式 HIGHLIGHT_STYLES = { Token.Keyword: {"foreground": "#FF7B72", "font": ("Consolas", 10, "bold")}, Token.String: {"foreground": "#A5D6FF"}, Token.Comment: {"foreground": "#6E7681", "font": ("Consolas", 10, "italic")}, Token.Number: {"foreground": "#79C0FF"}, Token.Name.Builtin: {"foreground": "#D2A8FF"}, Token.Operator: {"foreground": "#FF9BCE"}, Token.Punctuation: {"foreground": "#C9D1D9"}, Token.Name.Function: {"foreground": "#DCDCAA", "font": ("Consolas", 10, "bold")}, Token.Name.Class: {"foreground": "#4EC9B0", "font": ("Consolas", 10, "bold")}, } def highlight(text_widget): # 先清空所有旧的高亮标签 for tag in text_widget.tag_names(): text_widget.tag_remove(tag, "1.0", tk.END) # 获取文本框全部内容 code = text_widget.get("1.0", tk.END) lexer = PythonLexer() # 记录当前解析的位置偏移 pos = 0 for token, value in lexer.get_tokens(code): # 计算文本区间的起止位置 start = f"1.0 + {pos} chars" end = f"{start} + {len(value)} chars" # 匹配当前token对应的样式,添加标签 for token_type, style in HIGHLIGHT_STYLES.items(): if token in token_type: # 如果标签还没注册,先注册 if str(token_type) not in text_widget.tag_names(): text_widget.tag_configure(str(token_type), **style) text_widget.tag_add(str(token_type), start, end) break pos += len(value) if __name__ == "__main__": root = tk.Tk() root.title('Python IDE') # 设置文本框背景色、字体,和高亮样式适配 text = tk.Text(root, bg="#0D1117", fg="#C9D1D9", insertbackground="#C9D1D9", font=("Consolas", 10)) text.pack(fill=tk.BOTH, expand=True) # 绑定键盘松开事件,每次输入后触发高亮 def on_text_change(event): highlight(text) text.bind("<KeyRelease>", on_text_change) root.mainloop()
自定义调整说明
- 可以修改
HIGHLIGHT_STYLES字典中的配置,调整不同语法单元的颜色、字体大小、是否加粗斜体 - 深色背景不习惯的话可以把Text组件的
bg参数改成白色,对应调整各个高亮色值为深色系即可 - 如果需要优化大文件高亮性能,可以改为仅对可视区域内容做高亮,不用每次全量解析整个文本内容
内容的提问来源于stack exchange,提问作者johmin
相关产品推荐
相关产品推荐

