如何通过仅输入同一个窗口小部件来将文本输入到两个文本窗口小部件中

时间:2019-10-08 12:55:51

标签: python-3.x tkinter tkinter-text

我想要一种方法,通过将文本输入单个文本小部件中,可以将文本插入两个小部件中。我只想在编程中将文本小部件的所有功能和事件绑定到另一个文本小部件。 我尝试过

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

但这不是一个好的选择,因为它要花时间,并且会显示一些延迟,并且在文本变长时会显示较长的延迟。

2 个答案:

答案 0 :(得分:2)

如果您希望两个文本小部件的内容相同,则该文本小部件具有很少使用的功能,称为 peer小部件。实际上,您可以有多个共享相同基础数据结构的文本小部件。

canonical tcl/tk documentation描述了这样的同伴:

  

文本小部件具有单独存储的所有数据,这些数据涉及每一行的文本内容,标记,标签,图像和窗口以及撤消堆栈。

     

虽然无法直接访问此数据存储(即,没有文本窗口小部件作为中介),但是可以创建多个文本窗口小部件,每个文本窗口小部件在相同的基础数据上显示不同的视图。这种文本小部件称为对等文本小部件。

不幸的是,tkinter对文本小部件对等的支持不完整。但是,可以创建一个使用对等功能的新窗口小部件类。

以下内容定义了一个新的小部件TextPeer。它以另一个文本小部件为主,并创建一个对等方:

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

您使用的方法类似于使用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()

答案 1 :(得分:0)

我发现第二个框中更新文本的最快方法是使用replace()get()。也就是说,在测试完您的示例后,我并没有真正看到明显的延迟。

我们可以使用Modified事件来管理我们的更新,并且在每次修改之后,我们可以告诉text1 Modified为False,这样我们就可以获取每个更改的更新。

让我知道这是否是您想要的。

尝试一下:

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