Search code examples
pythonuser-interfacetexttkintertkinter-entry

Undo and Redo in an Tkinter Entry widget?


Is there a way to add undo and redo capabilities in Tkinter Entry widgets or must I use single line Text widgets for this type of functionality?

If the latter, are there any tips I should follow when configuring a Text widget to act as an Entry widget?

Some features that might need tweaking include trapping the Return KeyPress, converting tab keypresses into a request to change focus, and removing newlines from text being pasted from the clipboard.


Solution

  • Disclaimer: these are just thoughts that come into my mind on how to implement it.

    class History(object):
    
        def __init__(self):
            self.l = ['']
            self.i = 0
    
        def next(self):
            if self.i == len(self.l):
                return None
            self.i += 1
            return self.l[self.i]
    
        def prev(self):
            if self.i == 0:
                return None
            self.i -= 1
            return self.l[self.i]
    
        def add(self, s):
            del self.l[self.i+1:]
            self.l.append(s)
            self.i += 1
    
        def current(self):
            return self.l[self.i]
    

    Run a thread that every X seconds (0.5?) save the state of the entry:

    history = History()
    ...
    history.add(stringval.get())
    

    You can also set up events that save the Entry's status too, such as the pressure of Return.

    prev = history.prev()
    if prev is not None:
        stringvar.set(prev)
    

    or

    next = history.next()
    if next is not None:
        stringvar.set(next)
    

    Beware to set locks as needed.