Tkinter 文本小部件无法将“<”识别为单词的一部分
Tkinter Text widget not recognizing "<" as part of a word
我正在尝试使用 Tkinter 和 Python 3.10 制作一个简单的 HTML 编辑器。现在我正在尝试使用 Tkinter 文本小部件实现自动完成。该小部件会检查当前键入的单词,看它是否与 self._tags_list
中的任何 HTML 标签相匹配。如果是,它会自动完成它。
代码:
import random
import tkinter as tk
class IDE(tk.Text):
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
self._tags_list = ['<html></html>', '<head></head>', '<title></title>', '<body></body>', '<h1></h1>',
'<h2></h2>', '<h3></h3>', '<h4></h4>', '<h5></h5>', '<h6></h6>', '<p></p>', '<b></b>']
self.bind("<Any-KeyRelease>", self._autocomplete)
self.bind("<Tab>", self._completion, add=True)
self.bind("<Return>", self._completion, add=True)
def callback(self, word):
# Returns possible matches of `word`
matches = [x for x in self._tags_list if x.startswith(word)]
return matches
def _completion(self, _event):
tag_ranges = self.tag_ranges("autocomplete")
if tag_ranges:
self.mark_set("insert", tag_ranges[1])
self.tag_remove("sel", "1.0", "end")
self.tag_remove("autocomplete", "1.0", "end")
return "break"
def _autocomplete(self, event):
if event.keysym not in ["Return"] and not self.tag_ranges("sel"):
self.tag_remove("sel", "1.0", "end")
self.tag_remove("autocomplete", "1.0", "end")
word = self.get("insert-1c wordstart", "insert-1c wordend")
print(f"word: {word}")
matches = self.callback(word)
print(f"matches: {matches}")
if matches:
remainder = random.choice(matches)[len(word):]
print(remainder)
insert = self.index("insert")
self.insert(insert, remainder, ("sel", "autocomplete"))
self.mark_set("insert", insert)
return
if __name__ == "__main__":
window = tk.Tk()
window.title("Autocomplete")
window.geometry("500x500")
text = IDE(window)
text.pack(fill=tk.BOTH, expand=True)
window.mainloop()
从 使用。
当我输入“<”以启动 HTML 标记时,它会检测到第一个可能的自动完成(来自 self._tags_list
的随机标记减去开头的“<”)。但是,当我输入第二个字符时,它会将该字符检测为一个单独的单词并且不会自动完成。我用不以“<”开头的单词对其进行了测试,并且效果很好。
例如,当我在小部件中键入“
当我点击“<”时:
word: <
matches: ['<html></html>', '<head></head>', '<title></title>', '<body></body>', '<h1></h1>', '<h2></h2>', '<h3></h3>', '<h4></h4>', '<h5></h5>', '<h6></h6>', '<p></p>', '<b></b>']
remainder: h3></h3>
当我添加“h”时:
word: h
matches: []
Tkinter 图片window:
谁能告诉我为什么会这样以及如何解决?我已经检查了四周,但还没有发现任何东西。很抱歉,如果它很明显,但我现在正在学习 Tkinter。另外如果代码中还有其他问题,请告诉我。
wordstart
中的一个词被定义为
"a word is either a string of consecutive letter, digit, or underbar (_) characters, or a single character that is none of these types."
当您在 <
之后键入更多字符时,wordstart
从 <
旁边的字符开始。您可以通过在 wordstart
的末尾添加 -1c
来完成这项工作
word = self.get("insert -1c wordstart -1c", "insert -1c wordend")
通过添加
if "<" in word:
word = word[word.index("<"):]
在word
之后你可以有一点改善。
除此之外,您还需要从您的键符号中排除 BackSpace、Ctrl+a 等
我正在尝试使用 Tkinter 和 Python 3.10 制作一个简单的 HTML 编辑器。现在我正在尝试使用 Tkinter 文本小部件实现自动完成。该小部件会检查当前键入的单词,看它是否与 self._tags_list
中的任何 HTML 标签相匹配。如果是,它会自动完成它。
代码:
import random
import tkinter as tk
class IDE(tk.Text):
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
self._tags_list = ['<html></html>', '<head></head>', '<title></title>', '<body></body>', '<h1></h1>',
'<h2></h2>', '<h3></h3>', '<h4></h4>', '<h5></h5>', '<h6></h6>', '<p></p>', '<b></b>']
self.bind("<Any-KeyRelease>", self._autocomplete)
self.bind("<Tab>", self._completion, add=True)
self.bind("<Return>", self._completion, add=True)
def callback(self, word):
# Returns possible matches of `word`
matches = [x for x in self._tags_list if x.startswith(word)]
return matches
def _completion(self, _event):
tag_ranges = self.tag_ranges("autocomplete")
if tag_ranges:
self.mark_set("insert", tag_ranges[1])
self.tag_remove("sel", "1.0", "end")
self.tag_remove("autocomplete", "1.0", "end")
return "break"
def _autocomplete(self, event):
if event.keysym not in ["Return"] and not self.tag_ranges("sel"):
self.tag_remove("sel", "1.0", "end")
self.tag_remove("autocomplete", "1.0", "end")
word = self.get("insert-1c wordstart", "insert-1c wordend")
print(f"word: {word}")
matches = self.callback(word)
print(f"matches: {matches}")
if matches:
remainder = random.choice(matches)[len(word):]
print(remainder)
insert = self.index("insert")
self.insert(insert, remainder, ("sel", "autocomplete"))
self.mark_set("insert", insert)
return
if __name__ == "__main__":
window = tk.Tk()
window.title("Autocomplete")
window.geometry("500x500")
text = IDE(window)
text.pack(fill=tk.BOTH, expand=True)
window.mainloop()
从 self._tags_list
的随机标记减去开头的“<”)。但是,当我输入第二个字符时,它会将该字符检测为一个单独的单词并且不会自动完成。我用不以“<”开头的单词对其进行了测试,并且效果很好。
例如,当我在小部件中键入“ 当我点击“<”时: 当我添加“h”时: Tkinter 图片window: 谁能告诉我为什么会这样以及如何解决?我已经检查了四周,但还没有发现任何东西。很抱歉,如果它很明显,但我现在正在学习 Tkinter。另外如果代码中还有其他问题,请告诉我。word: <
matches: ['<html></html>', '<head></head>', '<title></title>', '<body></body>', '<h1></h1>', '<h2></h2>', '<h3></h3>', '<h4></h4>', '<h5></h5>', '<h6></h6>', '<p></p>', '<b></b>']
remainder: h3></h3>
word: h
matches: []
wordstart
中的一个词被定义为
"a word is either a string of consecutive letter, digit, or underbar (_) characters, or a single character that is none of these types."
当您在 <
之后键入更多字符时,wordstart
从 <
旁边的字符开始。您可以通过在 wordstart
-1c
来完成这项工作
word = self.get("insert -1c wordstart -1c", "insert -1c wordend")
通过添加
if "<" in word:
word = word[word.index("<"):]
在word
之后你可以有一点改善。
除此之外,您还需要从您的键符号中排除 BackSpace、Ctrl+a 等