PAYATHON 2026

Tkinter Entry 右键菜单为何不显示拼写建议?

数据阿明

原因

右键事件处理函数 _show_suggestions 只调用了 self.menu.tk_popup(...),没有检查当前文本或填充菜单。__spellcheck 只在 get() 中运行,所以在点击“Validate”之前,菜单是空的。

另外,调用 Menu.add_command 添加菜单项时,需要使用 label=。原代码中的 self.menu.add_command(suggestion) 没有将建议作为菜单标签传入。

修改方法

在右键处理函数中检查当前输入并清空旧菜单,再为每条拼写错误添加建议项。以下示例会用选中的建议替换对应的错误文本:

def __spellcheck(self, text):
    matches = self.tool.check(text)
    self.spelling_errors = []
    self.menu.delete(0, tk.END)

    for match in matches:
        if "EL_GR" in match.rule_id or "EN_US" in match.rule_id:
            self.spelling_errors.append(match)
            start = match.offset
            end = start + match.errorLength

            for suggestion in match.replacements:
                self.menu.add_command(
                    label=suggestion,
                    command=lambda s=suggestion, a=start, b=end: self._replace_error(a, b, s),
                )

    return self.spelling_errors

def _replace_error(self, start, end, suggestion):
    self.delete(start, end)
    self.insert(start, suggestion)

def _show_suggestions(self, event):
    self.__spellcheck(self.get())

    if self.menu.index("end") is not None:
        try:
            self.menu.tk_popup(event.x_root, event.y_root)
        finally:
            self.menu.grab_release()

lambda 中的默认参数会保存当前循环对应的建议和错误位置,避免点击菜单项时使用循环结束后的值。如果希望右键时即使没有建议也显示菜单,可以去掉 if self.menu.index("end") is not None: 条件。

注意事项

示例保留了代码中的 rule_id 筛选条件。如果某种语言或规则返回的拼写错误不符合这些条件,就不会出现在菜单中。可以根据实际的 match.rule_id 调整筛选逻辑。还需确认运行环境中的 LanguageTool 能正常检查文本;如果检查报错,应先处理该错误,否则菜单无法填充。

备注:内容仅供参考。