如何在Python Tkinter代码编辑器中实现{后自动换行缩进及补全}
实现Tkinter代码编辑器的括号自动换行缩进功能
要实现VSCode中输入{后按Enter自动换行、缩进并补全}的效果,需要修改现有代码的回车键绑定逻辑,同时调整括号补全的部分逻辑避免冲突。以下是具体修改方案:
步骤1:替换回车键绑定函数
将原来的autoIndent函数和<Return>绑定替换为能同时处理普通缩进和括号特殊场景的新函数:
def handle_return(event): # 获取当前插入位置的前一个字符 prev_char = event.widget.get("insert-1c", "insert") # 获取当前行内容与缩进级别 current_line_start = f"{event.widget.index('insert')} linestart" current_line_content = event.widget.get(current_line_start, f"{current_line_start} lineend") tab_count = len(current_line_content) - len(current_line_content.lstrip("\t")) # 针对{的特殊缩进逻辑 if prev_char == "{": event.widget.insert("insert", "\n") # 插入当前缩进+一级新缩进 event.widget.insert("insert", "\t" * (tab_count + 1)) # 插入换行与闭合},并将光标定位到中间缩进行 event.widget.insert("insert", f"\n{chr(9)*tab_count}}}") event.widget.mark_set("insert", "insert-1l") else: # 普通行自动缩进逻辑 event.widget.insert("insert", "\n") event.widget.insert("insert", "\t" * tab_count) # 阻止默认回车行为,避免重复换行 return "break"
步骤2:调整括号补全函数
原函数在输入{时的补全会干扰回车逻辑,需排除回车键场景:
def completeCharacter(event): # 跳过回车键,避免干扰换行逻辑 if event.keysym == "Return": return characterList = { '"': '"', "(": ")", "[": "]", "{": "}", "<": ">", } matching = characterList.get(event.char, None) if matching: event.widget.insert("insert", matching) event.widget.mark_set("insert", "insert-1c")
步骤3:更新事件绑定
替换原有的回车键绑定,保留括号补全绑定:
textBox.bind("<Return>", handle_return) textBox.bind('<Key>', completeCharacter)
完整修改后的代码
from tkinter import * from tkinter import font def handle_return(event): prev_char = event.widget.get("insert-1c", "insert") current_line_start = f"{event.widget.index('insert')} linestart" current_line_content = event.widget.get(current_line_start, f"{current_line_start} lineend") tab_count = len(current_line_content) - len(current_line_content.lstrip("\t")) if prev_char == "{": event.widget.insert("insert", "\n") event.widget.insert("insert", "\t" * (tab_count + 1)) event.widget.insert("insert", f"\n{chr(9)*tab_count}}}") event.widget.mark_set("insert", "insert-1l") else: event.widget.insert("insert", "\n") event.widget.insert("insert", "\t" * tab_count) return "break" def completeCharacter(event): if event.keysym == "Return": return characterList = { '"': '"', "(": ")", "[": "]", "{": "}", "<": ">", } matching = characterList.get(event.char, None) if matching: event.widget.insert("insert", matching) event.widget.mark_set("insert", "insert-1c") root = Tk() root.geometry("1200x600") root.title("Code Editor") mainFrame = Frame(root) mainFrame.pack(pady=0, fill="both", expand=True) YScroll = Scrollbar(mainFrame) YScroll.pack(side=RIGHT, fill=Y) XScroll = Scrollbar(mainFrame, orient="horizontal") XScroll.pack(side=BOTTOM, fill=X) fontName = StringVar(root) fontName.set("Consolas") fontSize = StringVar(root) fontSize.set("18") wrap = StringVar(value='none') textBox = Text(mainFrame, width=100, height=25, font=(fontName.get(), fontSize.get()), selectbackground="#FFFFBF", selectforeground="black", undo=True, yscrollcommand=YScroll.set, pady=10, padx=10, wrap=wrap.get(), xscrollcommand=XScroll.set) textBox.bind("<Return>", handle_return) textBox.bind('<Key>', completeCharacter) textBox.pack(fill="both", expand=True) tabNumber = 4 textFont = font.Font(font=textBox['font']) tab = textFont.measure(' ' * tabNumber) textBox.config(tabs=tab) if __name__ == "__main__": root.mainloop()
功能说明
- 输入
{后,自动补全}并将光标置于括号中间 - 按下回车键时,若前一个字符是
{,会自动换行并添加一级缩进,同时在下一行生成同级缩进的},光标停留在中间的缩进行 - 普通行按下回车键时,保持原有的自动缩进逻辑
内容的提问来源于stack exchange,提问作者Nuho Zubaed Salam
相关产品推荐
相关产品推荐

