如何在更改当前插入位置时在Tkinter中进行回调

2024-04-25 16:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我正在做一个与pythonttkinter共同编辑的项目。我需要捕捉用户更改插入索引位置时的事件。我使用Tkinter.文本作为对照。现在我只能捕捉<<modified>>虚拟事件,但是如何检测用户是否在不修改内容的情况下更改了编辑位置? 提前谢谢


Tags: 项目用户文本编辑内容tkinter事件情况
1条回答
网友
1楼 · 发布于 2024-04-25 16:33:19

有点令人惊讶的是,Tkinter没有直接内置的东西来解决这个问题。不过,还是有办法做你想做的。诀窍是用文本小部件拦截所有低级活动,然后生成应用程序可以绑定到的事件。在

例如,要在插入光标移动时获得通知,您需要在插入或删除内容或插入光标更改时(通过mark set insert命令)生成一个事件。在

我们可以设置一个代理来拦截所有这些命令。代理将把命令转发给原始的widget对象,当它检测到将更改插入点的命令时生成一个事件,然后返回原始命令的结果。在

下面是一个工作示例:

# for python3, use 'tkinter' instead of 'Tkinter'
import Tkinter as tk  

class Example(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.text = CustomText(self, background="white")
        self.status = tk.Label(self, bd=1, relief='sunken', text="", anchor="w")
        self.status.pack(side="bottom", fill="x")
        self.text.pack(side="right", fill="both", expand=True)

        self.text.bind("<<CursorChange>>", self._on_change)

        self.text.insert("end", "one\ntwo\nthree\n")
        self.text.insert("end", "four\n",("bigfont",))
        self.text.insert("end", "five\n")

    def _on_change(self, event):
        line, char = self.text.index("insert").split(".")
        message = "Line: %s character: %s" % (line, char)
        self.status.configure(text=message)


class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)

        # create a proxy for the underlying widget
        self._orig = self._w + "_orig"
        self.tk.call("rename", self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)

    def _proxy(self, *args):
        cmd = (self._orig,) + args
        result = self.tk.call(cmd)

        # generate an event if something was added or deleted,
        # or the cursor position changed
        if (args[0] in ("insert", "delete") or 
            args[0:3] == ("mark", "set", "insert")):
            self.event_generate("<<CursorChange>>", when="tail")

        return result        


if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True);
    root.mainloop()

相关问题 更多 >