F
F
Fizl2021-06-13 12:13:44
Python
Fizl, 2021-06-13 12:13:44

How to show change in text document via Text?

Let's say there is some text.txt file. I need to output it with Text, but also pad its content if it was somehow changed while the program was running. Help me please

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Petrenko, 2021-06-13
@Fizl

You can set up a proxy for a widget, and in that proxy you can determine when something has been inserted or removed. You can use this information to create a virtual event that can be linked to any other event.
Let's start by creating our own text widget class, which you will use like any other text widget:

import Tkinter as tk

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

The proxy server in this example performs three functions:
1. It first invokes the actual widget command, passing in any arguments it receives.
2. Then it generates an event for every insert and every delete.
3. It then fires a virtual event
4. And finally, it returns the results of the actual widget command.
You can use this widget just like any other text widget, with the added benefit that you can bind to <>.
For example, if you want to display the number of characters in a text widget, you can do something like this:
root = tk.Tk()
label = tk.Label(root, anchor="w")
text = CustomText(root, width=40, height=4)

label.pack(side="bottom", fill="x")
text.pack(side="top", fill="both", expand=True)

def onModification(event):
    chars = len(event.widget.get("1.0", "end-1c"))
    label.configure(text="%s chars" % chars)

text.bind("<<TextModified>>", onModification)

root.mainloop()

And you just have to screw it all on the usual interaction with the "text.txt" file

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question