如何显示一个带有拼写纠错建议的菜单?

编程语言 2026-07-11

我正在做一个带有拼写检查功能的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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章