0

I have bound a event to a text widget in order to follow all the changes in its text. This event is called before the new character is added to the widget's text. What I need is a event that's called after the new character has been added, or something similar.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Rawing
  • 19
  • 1
  • 1
  • 2
  • possible duplicate of [How to bind self events in Tkinter Text widget after it will binded by Text widget?](http://stackoverflow.com/questions/3501849/how-to-bind-self-events-in-tkinter-text-widget-after-it-will-binded-by-text-widg). Technically this isn't a duplicate because it was asked first but the other question got better answers, possibly because it was properly tagged with "tkinter" when it was written. – Bryan Oakley Jan 03 '14 at 18:27

1 Answers1

0

Here's a small change of a Cookbook recipe that I believe does what you want:

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()

I've left the whole structure, comments included, intact; the change is to the print, to make it a function and to show the widget's current contents to confirm that they're the contents after the modification, as you require.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • oooo-kay. Didn't understand everything; but this seems to kill tkinter's event. I need an event before modification and one after modification. Plus, if this only works with Text widgets it'll be a pain to add an after-configure event for all widgets. – Rawing Aug 10 '10 at 16:07