Как ввести текст в два текстовых виджета, просто введя в один и тот же виджет - PullRequest
1 голос
/ 08 октября 2019

Мне нужен метод, с помощью которого я могу вставлять текст в два виджета, вводя текст в один текстовый виджет. Просто в программировании я хочу связать все функции и события текстового виджета с другим текстовым виджетом. я пробовал

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 ]

2 голосов
/ 08 октября 2019

Если вы хотите, чтобы содержимое двух текстовых виджетов было идентичным, текстовый виджет имеет мало используемую функцию, известную как равноправные виджеты . В сущности, вы можете иметь несколько текстовых виджетов, которые разделяют одну и ту же базовую структуру данных.

Каноническая документация 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()
0 голосов
/ 08 октября 2019

Самый быстрый способ обновить текст во 2-м поле, которое я нашел, - это использовать 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()
...