In python 2.7, I am trying to get a callback every time something is changed in the Tkinter Text widget.
The program uses multiple frames based on code found here: Switch between two frames in tkinter?
The callback part is taken from the following example: http://code.activestate.com/recipes/464635-call-a-callback-when-a-tkintertext-is-modified/
Both codes work fine separately, but combining those two is difficult for me. Here is my attempt with as bare bones code as possible.
import Tkinter as tk
class Texter(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack()
        self.frames = {}
        for F in (ConnectPage, EditorPage):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        page_name = EditorPage.__name__
        self.frames[page_name] = frame
        self.show_frame(ConnectPage)
    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()
    def get_page(self, page_name):
        return self.frames[page_name]
class ConnectPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        button1 = tk.Button(self, text="SecondPage",
                            command=lambda: controller.show_frame(EditorPage))
        button1.grid(row=2, column=3, padx=15)
class EditorPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self, height=25, width=80)
        self.text.grid(column=0, row=0, sticky="nw")
        button2 = tk.Button(self, text="FirstPage",
                            command=lambda: controller.show_frame(ConnectPage))
        button2.grid(row=2, column=3, padx=15)
        self.clearModifiedFlag()
        self.bind_all('<<Modified>>', self._beenModified)
    def _beenModified(self, event=None):
        if self._resetting_modified_flag: return
        self.clearModifiedFlag()
        print("Hello!")
        #self.beenModified(event)
    def clearModifiedFlag(self):
        self._resetting_modified_flag = True
        try:
            self.tk.call(self._w, 'edit', 'modified', 0)
        finally:
            self._resetting_modified_flag = False
if __name__ == '__main__':
    gui = Texter()
    gui.mainloop()
I tried taking only the necessary parts from the callback example. The code does do a callback (if self.tk.call(self._w, 'edit', 'modified', 0) line is commented out) when the text is modified, but resetting the modified flag does not work, so only the first modification is registered.
At the moment I get the following error:
line 67, in clearModifiedFlag
self.tk.call(self._w, 'edit', 'modified', 0)
_tkinter.TclError: bad option "edit": must be cget or configure
In the callback example code "edit" works fine.
This is the working code
import Tkinter as tk
class Texter(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack()
        self.frames = {}
        for F in (ConnectPage, EditorPage):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        page_name = EditorPage.__name__
        self.frames[page_name] = frame
        self.show_frame(ConnectPage)
    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()
    def get_page(self, page_name):
        return self.frames[page_name]
class ConnectPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        button1 = tk.Button(self, text="SecondPage",
                            command=lambda: controller.show_frame(EditorPage))
        button1.grid(row=2, column=3, padx=15)
class EditorPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.text = CustomText(self, height=25, width=80)
        self.text.grid(column=0, row=0, sticky="nw")
        self.text.bind("<<TextModified>>", self.onModification)
        button2 = tk.Button(self, text="FirstPage",
                            command=lambda: controller.show_frame(ConnectPage))
        button2.grid(row=2, column=3, padx=15)
    def onModification(self, event):
        print("Yellow!")
class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        """A text widget that report on internal widget commands"""
        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, command, *args):
        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)
        if command in ("insert", "delete", "replace"):
            self.event_generate("<<TextModified>>")
        return result
if __name__ == '__main__':
    gui = Texter()
    gui.mainloop()