如何显示一个带有拼写纠错建议的菜单?
我正在做一个带有拼写检查功能的tkEntry:
# Source - https://stackoverflow.com/q/79905735
# Posted by Dimitrios Desyllas
# Retrieved 2026-03-12, License - CC BY-SA 4.0
import tkinter as tk
import language_tool_python
class SpellCheckEntry(tk.Entry):
def __init__(self, master=None, pure_english:bool=False, **kwargs):
self.var = tk.StringVar()
super().__init__(master, textvariable=self.var, **kwargs)
language = "en_US" if pure_english else "auto"
print(language)
self.tool = language_tool_python.LanguageTool(language)
self.spelling_errors=[]
self.menu = tk.Menu(self, tearoff=0)
self.bind("<Button-3>", self._show_suggestions)
def __spellcheck(self,text):
matches = self.tool.check(text)
self.menu.delete(0, tk.END)
self.spelling_errors=[]
for m in matches:
if("EL_GR" in (m.rule_id) or "EN_US" in (m.rule_id)):
self.spelling_errors.append(m)
print("Matching Rule",m.rule_id)
if self.spelling_errors:
self.configure(highlightbackground="red", highlightcolor="red")
for error in self.spelling_errors:
for suggestion in error.replacements:
self.menu.add_command(suggestion)
else:
self.configure(highlightbackground="gray")
return self.spelling_errors
def _show_suggestions(self,event):
try:
self.menu.tk_popup(event.x_root, event.y_root)
finally:
self.menu.grab_release()
def get(self):
text = super().get().strip()
errors = self.__spellcheck(text)
if errors:
raise ValueError(f"Spelling errors detected: {text}")
return text
def submit():
try:
value = entry.get()
print("Valid text:", value)
except ValueError as e:
print(e)
root = tk.Tk()
root.title("SpellCheckEntry Demo")
root.geometry("400x150")
tk.Label(root, text="Type something:").pack(pady=5)
entry = SpellCheckEntry(root, pure_english=True, width=40)
entry.pack(pady=5)
btn = tk.Button(root, text="Validate", command=submit)
btn.pack(pady=10)
root.mainloop()
我的目标是当输入框存在拼写检查错误时,显示一个带有修改建议的菜单。
但目前当我在Entry上右键单击时,尽管我故意输入了一个拼写错误的单词,仍然没有显示菜单。
你知道这是为什么吗?
解决方案
在你的代码中,问题出在:
for error in self.spelling_errors:
for suggestion in error.replacements:
self.menu.add_command(suggestion)
原因是因为点击后没有触发任何回调函数来执行该操作。 你可以做的最小修复是:
for error in self.spelling_errors:
for suggestion in error.replacements:
self.menu.add_command(label=suggestion,command=lambda s=suggestion: self._apply_suggestion(s))
然后放置这个方法:
def _apply_suggestion(self, text):
self.delete(0, tk.END)
self.insert(0, text)
self.spelling_errors.clear()
self.configure(highlightbackground="gray")
这个函数的作用是用建议的值覆盖输入框中的内容。
最终脚本是:
import tkinter as tk
import language_tool_python
class SpellCheckEntry(tk.Entry):
def __init__(self, master=None, pure_english:bool=False, **kwargs):
self.var = tk.StringVar()
super().__init__(master, textvariable=self.var, **kwargs)
language = "en_US" if pure_english else "auto"
print(language)
self.tool = language_tool_python.LanguageTool(language)
self.spelling_errors=[]
self.menu = tk.Menu(self, tearoff=0)
self.bind("<Button-3>", self._show_suggestions)
def __spellcheck(self,text):
matches = self.tool.check(text)
self.menu.delete(0, tk.END)
self.spelling_errors=[]
for m in matches:
if("EL_GR" in (m.rule_id) or "EN_US" in (m.rule_id)):
self.spelling_errors.append(m)
print("Matching Rule",m.rule_id)
if self.spelling_errors:
self.configure(highlightbackground="red", highlightcolor="red")
for error in self.spelling_errors:
for suggestion in error.replacements:
# FIX: Placing a callback here
self.menu.add_command(
label=suggestion,
command=lambda s=suggestion: self._apply_suggestion(s)
)
else:
self.configure(highlightbackground="gray")
return self.spelling_errors
#FIX: Callback that applies data upon input
def _apply_suggestion(self, text):
self.delete(0, tk.END)
self.insert(0, text)
self.spelling_errors.clear()
self.configure(highlightbackground="gray")
def _show_suggestions(self,event):
try:
self.menu.tk_popup(event.x_root, event.y_root)
finally:
self.menu.grab_release()
def get(self):
text = super().get().strip()
errors = self.__spellcheck(text)
if errors:
raise ValueError(f"Spelling errors detected: {text}")
return text
def submit():
try:
value = entry.get()
print("Valid text:", value)
except ValueError as e:
print(e)
root = tk.Tk()
root.title("SpellCheckEntry Demo")
root.geometry("400x150")
tk.Label(root, text="Type something:").pack(pady=5)
entry = SpellCheckEntry(root, pure_english=True, width=40)
entry.pack(pady=5)
btn = tk.Button(root, text="Validate", command=submit)
btn.pack(pady=10)
root.mainloop()
请注意以下方法:
__spellcheck_apply_suggestion
我在这些地方做了修改。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。