2

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

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

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

4

2 回答 2

4

如果您希望两个文本小部件的内容相同,则文本小部件有一个很少使用的功能,称为对等小部件。实际上,您可以拥有多个共享相同底层数据结构的文本小部件。

规范的tcl/tk 文档描述了这样的对等点:

文本小部件有一个单独的存储区,用于存储与每一行的文本内容、标记、标签、图像和窗口以及撤消堆栈有关的所有数据。

虽然无法直接访问此数据存储(即没有文本小部件作为中介),但可以创建多个文本小部件,每个文本小部件呈现相同底层数据的不同视图。这样的文本小部件被称为对等文本小部件。

不幸的是,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()
于 2019-10-08T16:04:11.973 回答
0

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

我们可以使用该Modified事件来管理我们的更新,并且在每次修改之后,我们可以判断text1Modified是 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()
于 2019-10-08T13:08:15.067 回答