如何从 _proxy 方法中返回一个事件?

huangapple go评论74阅读模式
英文:

how to return a event from the _proxy method?

问题

In Python 3.8中,我正在尝试每当 tkinter Text 小部件中的内容更改时获取回调。

import tkinter as tk

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

        self._orig = self._w + "_orig"
        self.tk.call("rename", self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)

        self.scrollbar_ver = tk.Scrollbar(self, orient=tk.VERTICAL)

    def _proxy(self, command, *args):
        if command == 'get' and args == ('sel.first', 'sel.last') and not self.tag_ranges('sel'):
            return

        if command == 'delete' and args == ('sel.first', 'sel.last') and not self.tag_ranges('sel'):
            return

        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)

        if command in ('insert', 'delete', 'replace'):
            self.event_generate('<<TextModified>>', data=f"Command: {command}, Args: {args}")

        return result

def callback(event: tk.Event):
    print(event.keysym)
    print(event.data)  # This will print the additional info you attached.

root = tk.Tk()

text = CustomText(root)
text.pack()
text.bind('<<TextModified>>', callback)

root.mainloop()

我想从事件中获取一些信息,例如 keycode 或 keysym。但这似乎是不可能的,因为事件在生成时没有任何信息。您可以在生成 TextModified 事件时附加信息,像这样做。

英文:

In python 3.8,I am trying to get a callback every time something is changed in the tkinter Text widget.

import tkinter as tk


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

        self._orig = self._w + &quot;_orig&quot;
        self.tk.call(&quot;rename&quot;, self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)

        self.scrollbar_ver = tk.Scrollbar(self, orient=tk.VERTICAL)

    def _proxy(self, command, *args):
        if command == &#39;get&#39; and args == (&#39;sel.first&#39;, &#39;sel.last&#39;) and not self.tag_ranges(&#39;sel&#39;):
            return

        if command == &#39;delete&#39; and args == (&#39;sel.first&#39;, &#39;sel.last&#39;) and not self.tag_ranges(&#39;sel&#39;):
            return

        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)

        if command in (&#39;insert&#39;, &#39;delete&#39;, &#39;replace&#39;):
            self.event_generate(&#39;&lt;&lt;TextModified&gt;&gt;&#39;)

        return result


def callback(event: tk.Event):
    print(event.keysym)


root = tk.Tk()

text = CustomText(root)
text.pack()
text.bind(&#39;&lt;&lt;TextModified&gt;&gt;&#39;, callback)

root.mainloop()

I want to get some info from the event, such as keycode or keysym. But that's impossible because the event is generated without any info. How can I attach the info when I generate the TextModified event?

答案1

得分: 0

以下是您要翻译的内容:

You cannot directly send this kind of information through the generated event.
However, you can store in an attribute of the widget the desired information about the executed command and retrieve it in the callback:

import tkinter as tk

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

        self._orig = self._w + "_orig"
        self.tk.call("rename", self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)
        
        self.event_info = "" # attribute to store the info
        self.scrollbar_ver = tk.Scrollbar(self, orient=tk.VERTICAL)

    def _proxy(self, command, *args):
        if command == 'get' and args == ('sel.first', 'sel.last') and not self.tag_ranges('sel'):
            return

        if command == 'delete' and args == ('sel.first', 'sel.last') and not self.tag_ranges('sel'):
            return

        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)

        if command in ('insert', 'delete', 'replace'):
            self.event_info = command  # <- store whatever info you need about the command there
            self.event_generate('<<TextModified>>')

        return result


def callback(event: tk.Event):
    print(event.widget.event_info)  # retrieve the info about the command

root = tk.Tk()

text = CustomText(root)
text.pack()
text.bind('<<TextModified>>', callback)

root.mainloop()

我已经将代码部分翻译好,如有需要,请继续。

英文:

You cannot directly send this kind of information through the generated event.
However, you can store in an attribute of the widget the desired information about the executed command and retrieve it in the callback:

import tkinter as tk

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

        self._orig = self._w + &quot;_orig&quot;
        self.tk.call(&quot;rename&quot;, self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)
        
        self.event_info = &quot;&quot; # attribute to store the info
        self.scrollbar_ver = tk.Scrollbar(self, orient=tk.VERTICAL)

    def _proxy(self, command, *args):
        if command == &#39;get&#39; and args == (&#39;sel.first&#39;, &#39;sel.last&#39;) and not self.tag_ranges(&#39;sel&#39;):
            return

        if command == &#39;delete&#39; and args == (&#39;sel.first&#39;, &#39;sel.last&#39;) and not self.tag_ranges(&#39;sel&#39;):
            return

        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)

        if command in (&#39;insert&#39;, &#39;delete&#39;, &#39;replace&#39;):
            self.event_info = command  # &lt;- store whatever info you need about the command there
            self.event_generate(&#39;&lt;&lt;TextModified&gt;&gt;&#39;)

        return result


def callback(event: tk.Event):
    print(event.widget.event_info)  # retrieve the info about the command

root = tk.Tk()

text = CustomText(root)
text.pack()
text.bind(&#39;&lt;&lt;TextModified&gt;&gt;&#39;, callback)

root.mainloop()

I am aware this is not exactly what was asked in the question since this is not a keysym or keycode. When the proxy function is called, we do not know what triggered the command so it is difficult to get the exact keysym/keycode. However, I do not know what kind of callback the OP wants to implement, so maybe the necessary information for that can be determined from the command arguments, e.g. what characters were added/deleted.

If what is really needed is a keysym/keycode, then one has to use a binding to &lt;Key&gt;.

huangapple
  • 本文由 发表于 2023年7月6日 15:04:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76626265.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定