我有这个“输出”函数,调用时会将为第一个参数提供的文本插入到 tkinter 文本框中,并向其添加第二个参数颜色的标签(请参见下面的代码)
def Output(text, tagcol):
global OutputLine
responsezone.insert(END, f"{text}\n")
OutputLine += 1
if tagcol != "None":
responsezone.tag_add(tagcol, f"{OutputLine}.0", END)
responsezone.tag_config(tagcol, foreground = tagcol)
例如,如果我有这样的代码:
Output("This text is Red", "red")
Output("This text is Yellow", "yellow)
输出应该是第一行是红色,第二行是黄色,但对我来说,我得到了 2 条红线,我不太确定为什么。
该项目所在的代码可以随时调用Output(),因此无法预测输出的文本(如使用代码手动为每一行添加标签)。
这是供您测试的代码:
from tkinter import *
import customtkinter as CT
OutputLine = 0
root = CT.CTk()
root.geometry("1050x750")
responsezone = CT.CTkTextbox(master = root, height = 150, width = 1000, yscrollcommand = True, fg_color = "gray16", font = ("Consolas", 15))
responsezone.place(x = 25, y = 550)
def Output(text, tagcol):
global OutputLine
responsezone.insert(END, f"{text}\n")
OutputLine += 1
if tagcol != "None":
responsezone.tag_add(tagcol, f"{OutputLine}.0", END)
responsezone.tag_config(tagcol, foreground = tagcol)
root.bind("<F5>", lambda event: Output("Red", "red")) # F5 Keybind
root.bind("<F6>", lambda event: Output("Yellow", "yellow")) # F5 Keybind
root.mainloop()```
您遇到的问题是由于您在
Output
函数中应用标签的方式造成的。当您在 END
中使用 responsezone.tag_add(tagcol, f"{OutputLine}.0", END)
时,您会无意中从行首一直应用到文本小部件的末尾。这意味着您在此标记文本之后插入的任何新行也将继承相同的标记和颜色,从而导致两行均显示为红色。
END
代表文本的当前结束位置:在 Tkinter 中,END
指的是小部件中文本的当前结束位置。每次插入新文本时,END
都会移动到新的末尾。
标签应用于指定范围:当您将标签从起始索引应用到
END
时,它会影响从该起始索引到文本小部件当前结尾的所有文本。如果 END
由于插入额外的文本而移动,则先前定义的标签将扩展以覆盖新文本,除非受到适当的约束。
要解决此问题,您需要在插入文本后立即精确选择要标记的文本范围。
from tkinter import *
import customtkinter as CT
OutputLine = 0
root = CT.CTk()
root.geometry("600x400")
responsezone = CT.CTkTextbox(master=root, height=150, width=500, yscrollcommand=True, fg_color="gray16", font=("Consolas", 15))
responsezone.place(x=25, y=100)
def Output(text, tagcol):
index_start = responsezone.index('end-1c linestart')
responsezone.insert(END, f"{text}\n")
index_end = responsezone.index('end-1c') # Before the newline
if tagcol != "None":
responsezone.tag_add(tagcol, index_start, index_end)
responsezone.tag_config(tagcol, foreground=tagcol)
root.bind("<F5>", lambda event: Output("This text is Red", "red")) # F5 Keybind
root.bind("<F6>", lambda event: Output("This text is Yellow", "yellow")) # F6 Keybind
OutputLine = 1
root.mainloop()