<p>我发现问题中提出的类并没有像典型的Tkinter小部件那样处理textvariable,所以我自己做了一些重写,使其成为一个“适当的”小部件。:-)</p>
<p>通常,textvariable实例不会被传递给它的类修改,而是在变量更改时调用它的get()函数(通过跟踪检测),而set()函数则通过某个内部钩子调用。这样,它可以被其他小部件使用。此外,猴子修补也许不是最安全的做法。</p>
<p>在本例中,使用文本小部件绑定方法和<code><<Modified>></code>标记。它不是一个典型的持续触发的“on_change”事件,而是在有人修改小部件的内容时触发的,它提供了一种机制来帮助发出值已被修改的信号。因此,每次触发后,需要使用Text.edit_modified(False)和var_modified函数重置它,以便再次触发。但它起作用了,我没有得到<code><<Change>></code>为我工作。</p>
<p>最后,为了避免不需要的循环,文本变量的跟踪在文本修改中被暂时禁用。此外,如果小部件用于显式删除父项的情况(如在模式窗口中),则应调用unhook()方法进行清理,以避免出现问题。如果没有,就可以无视。</p>
<p>给你:</p>
<pre><code>from tkinter import Frame, Variable, Scrollbar, Text
from tkinter.constants import VERTICAL, RIGHT, LEFT, BOTH, END, Y
class TextExtension(Frame):
"""Extends Frame. Intended as a container for a Text field. Better related data handling
and has Y scrollbar."""
def __init__(self, master, textvariable=None, *args, **kwargs):
super(TextExtension, self).__init__(master)
# Init GUI
self._y_scrollbar = Scrollbar(self, orient=VERTICAL)
self._text_widget = Text(self, yscrollcommand=self._y_scrollbar.set, *args, **kwargs)
self._text_widget.pack(side=LEFT, fill=BOTH, expand=1)
self._y_scrollbar.config(command=self._text_widget.yview)
self._y_scrollbar.pack(side=RIGHT, fill=Y)
if textvariable is not None:
if not (isinstance(textvariable, Variable)):
raise TypeError("tkinter.Variable type expected, " + str(type(textvariable)) + " given.".format(type(textvariable)))
self._text_variable = textvariable
self.var_modified()
self._text_trace = self._text_widget.bind('<<Modified>>', self.text_modified)
self._var_trace = textvariable.trace("w", self.var_modified)
def text_modified(self, *args):
if self._text_variable is not None:
self._text_variable.trace_vdelete("w", self._var_trace)
self._text_variable.set(self._text_widget.get(1.0, END))
self._var_trace = self._text_variable.trace("w", self.var_modified)
self._text_widget.edit_modified(False)
def var_modified(self, *args):
self.set_text(self._text_variable.get())
self._text_widget.edit_modified(False)
def unhook(self):
if self._text_variable is not None:
self._text_variable.trace_vdelete("w", self._var_trace)
def clear(self):
self._text_widget.delete(1.0, END)
def set_text(self, _value):
self.clear()
if (_value is not None):
self._text_widget.insert(END, _value)
</code></pre>
<p>您可以在这里的<a href="https://sourceforge.net/p/optimalbpm/code/ci/master/tree/optimalbpm/tools/gui/main_tk_replicator.py#l120" rel="nofollow">on_post_merge_sql-function</a>中看到正在使用和使用unhook的代码。</p>
<p>干杯!</p>