3

I want a method from which I can insert text into two widgets by entering text into single text widget. Simply in programming is I want to bind all functions and events of text widget to another text widget. i had tried

txt=Text(root,height=300,width=300)
txt.pack()
text=Text(root,height=300,width=300)
text.pack()
def func(event):
    text.delete("1.0","end")
    text.insert(INSERT,txt.get("1.0","end"))
txt.bind(func,<Any-KeyPress>)

but it is not a good option because it is taking time and it shows some delay, and some long delay when the text goes long.

Kumar Saptam
  • 336
  • 5
  • 18
  • You have a syntax error and `insert` will raise `insert() takes at least 3 arguments (2 given)` – Kenly Oct 08 '19 at 13:28
  • I have updated my answer to use on of the built in trackers for text widgets to update on modify. Let me know if that was what you were looking for. – Mike - SMT Oct 08 '19 at 14:08

2 Answers2

5

If you want the contents of the two text widgets to be identical, the text widget has a little-used feature known as peer widgets. In effect, you can have multiple text widgets that share the same underlying data structure.

The canonical tcl/tk documentation describes peers like this:

The text widget has a separate store of all its data concerning each line's textual contents, marks, tags, images and windows, and the undo stack.

While this data store cannot be accessed directly (i.e. without a text widget as an intermediary), multiple text widgets can be created, each of which present different views on the same underlying data. Such text widgets are known as peer text widgets.

Unfortunately, tkinter's support of text widget peering is not complete. However, it's possible to create a new widget class that makes use of the peering function.

The following defines a new widget, TextPeer. It takes another text widget as its master and creates a peer:

import tkinter as tk

class TextPeer(tk.Text):
    """A peer of an existing text widget"""
    count = 0
    def __init__(self, master, cnf={}, **kw):
        TextPeer.count += 1
        parent = master.master
        peerName = "peer-{}".format(TextPeer.count)
        if str(parent) == ".":
            peerPath = ".{}".format(peerName)
        else:
            peerPath = "{}.{}".format(parent, peerName)

        # Create the peer
        master.tk.call(master, 'peer', 'create', peerPath, *self._options(cnf, kw))

        # Create the tkinter widget based on the peer
        # We can't call tk.Text.__init__ because it will try to
        # create a new text widget. Instead, we want to use
        # the peer widget that has already been created.
        tk.BaseWidget._setup(self, parent, {'name': peerName})

You use this similar to how you use a Text widget. You can configure the peer just like a regular text widget, but the data will be shared (ie: you can have different sizes, colors, etc for each peer)

Here's an example that creates three peers. Notice how typing in any one of the widgets will update the others immediately. Although these widgets share the same data, each can have their own cursor location and selected text.

import tkinter as tk

root = tk.Tk()

text1 = tk.Text(root, width=40, height=4, font=("Helvetica", 20))
text2 = TextPeer(text1, width=40, height=4, background="pink", font=("Helvetica", 16))
text3 = TextPeer(text1, width=40, height=8, background="yellow", font=("Fixed", 12))

text1.pack(side="top", fill="both", expand=True)
text2.pack(side="top", fill="both", expand=True)
text3.pack(side="top", fill="both", expand=True)


text2.insert("end", (
    "Type in one, and the change will "
    "appear in the other."
))
root.mainloop()
Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

The quickest way to update text in a 2nd box that I have found is to use replace() and get(). That said after testing your example I am not really seeing a noticeable delay.

We can use the Modified event to manage our updates and after each modification we can tell text1 that Modified is False so we get an update on every change.

Let me know if this was what you were looking for.

Try this:

import tkinter as tk


def update_text2(_=None):
    text2.replace('1.0', 'end', text1.get('1.0', 'end'))
    text1.edit_modified(False)


root = tk.Tk()
text1 = tk.Text(root)
text2 = tk.Text(root)
text1.pack()
text2.pack()

text1.bind('<<Modified>>', update_text2)

root.mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • IT shows delay because i am using syntax highlighting so that class uses to much of find and replace and also add too much of tags to text which led to slow down of coloring, but thanks for your answer else Bryan answer worked more effectively. – Kumar Saptam Oct 10 '19 at 04:47