обратный вызов tkinter ПОСЛЕ изменения

Я привязал событие к текстовому виджету, чтобы следить за всеми изменениями в его тексте. Это событие вызывается перед добавлением нового символа в текст виджета. Мне нужно событие, которое вызывается после добавления нового персонажа или что-то подобное.


person Rawing    schedule 09.08.2010    source источник
comment
возможный дубликат Как связать собственные события в виджете Tkinter Text после того, как он будет привязан виджетом Text?. Технически это не дубликат, потому что он был задан первым, но на другой вопрос были получены лучшие ответы, возможно, потому, что он был правильно помечен tkinter, когда он был написан.   -  person Bryan Oakley    schedule 03.01.2014


Ответы (1)


Вот небольшое изменение в рецепте из поваренной книги, которое, как мне кажется, делает то, что вам нужно:

class ModifiedMixin:
    '''
    Class to allow a Tkinter Text widget to notice when it's modified.

    To use this mixin, subclass from Tkinter.Text and the mixin, then write
    an __init__() method for the new class that calls _init().

    Then override the beenModified() method to implement the behavior that
    you want to happen when the Text is modified.
    '''

    def _init(self):
        '''
        Prepare the Text for modification notification.
        '''

        # Clear the modified flag, as a side effect this also gives the
        # instance a _resetting_modified_flag attribute.
        self.clearModifiedFlag()

        # Bind the <<Modified>> virtual event to the internal callback.
        self.bind_all('<<Modified>>', self._beenModified)

    def _beenModified(self, event=None):
        '''
        Call the user callback. Clear the Tk 'modified' variable of the Text.
        '''

        # If this is being called recursively as a result of the call to
        # clearModifiedFlag() immediately below, then we do nothing.
        if self._resetting_modified_flag: return

        # Clear the Tk 'modified' variable.
        self.clearModifiedFlag()

        # Call the user-defined callback.
        self.beenModified(event)

    def beenModified(self, event=None):
        '''
        Override this method in your class to do what you want when the Text
        is modified.
        '''
        pass

    def clearModifiedFlag(self):
        '''
        Clear the Tk 'modified' variable of the Text.

        Uses the _resetting_modified_flag attribute as a sentinel against
        triggering _beenModified() recursively when setting 'modified' to 0.
        '''

        # Set the sentinel.
        self._resetting_modified_flag = True

        try:

            # Set 'modified' to 0.  This will also trigger the <<Modified>>
            # virtual event which is why we need the sentinel.
            self.tk.call(self._w, 'edit', 'modified', 0)

        finally:
            # Clean the sentinel.
            self._resetting_modified_flag = False


if __name__ == '__main__':
    from Tkinter import Text, BOTH, END

    class T(ModifiedMixin, Text):
        '''
        Subclass both ModifiedMixin and Tkinter.Text.
        '''

        def __init__(self, *a, **b):

            # Create self as a Text.
            Text.__init__(self, *a, **b)

            # Initialize the ModifiedMixin.
            self._init()

        def beenModified(self, event=None):
            '''
            Override this method do do work when the Text is modified.
            '''
            print('Hi there.', self.get(1.0, END))

    t = T()
    t.pack(expand=1, fill=BOTH)
    t.mainloop()

Я оставил всю структуру, включая комментарии, нетронутой; изменение заключается в print, чтобы сделать его функцией и показать текущее содержимое виджета, чтобы подтвердить, что оно является содержимым после модификации, как вам требуется.

person Alex Martelli    schedule 10.08.2010
comment
ооо-кей. Не все понял; но это, кажется, убивает событие ‹configure› tkinter. Мне нужно событие до модификации и одно после модификации. Кроме того, если это работает только с текстовыми виджетами, будет сложно добавить событие после настройки для всех виджетов. - person Rawing; 10.08.2010