Я пытаюсь добавить небольшое автоматическое поле в текстовый виджет, но мне сложно писать теги.

У меня есть текстовое поле, и я пытаюсь вставить текст в это поле, сохраняя поле.

Я могу получить вставленный текст, чтобы иметь поле, но когда я набираю текст за последней строкой, поле исчезает. Пока все, что я могу выкопать, это как написать тег и использовать его с insert(), но я хочу всегда сохранять поле.

Вопрос: есть ли способ сохранить поле для всех строк, а не только для тех, которые были вставлены из файла или строки?

Обратите внимание, что тот же вопрос распространяется на тег Offset, потому что я испытываю ту же проблему при наборе текста после вставленного текста.

Вот что я пробовал в примере минимального, полного и проверяемого.

import tkinter as tk


root = tk.Tk()

text = tk.Text(root, width = 10, height = 10)
text.pack()

text.tag_configure("marg", lmargin1 = 10, lmargin2 = 10)
text.insert("end", "Some random text!", ("marg"))

root.mainloop()

enter image description here

3
Mike - SMT 13 Мар 2018 в 20:13

2 ответа

Лучший ответ

К сожалению, крайние случаи добавления и удаления текста в самом начале и в конце виджета затрудняют работу с тегами.

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

Например, начните с пользовательского виджета, который генерирует событие <<TextModified>> каждый раз, когда виджет изменяется:

class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        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

(см. https://stackoverflow.com/a/40618152/7432)

Затем измените вашу программу, чтобы использовать этот прокси, чтобы тег маржи всегда применялся ко всему содержимому:

def add_margin(event):
    event.widget.tag_add("marg", "1.0", "end")

text = CustomText(root, width = 10, height = 6)
text.bind("<<TextModified>>", add_margin)
2
Bryan Oakley 13 Мар 2018 в 17:55

Если вы добавите тег ко всему диапазону текста (включая последний завершающий символ новой строки), то введенные вами новые символы наследуют этот тег.

Добавьте следующее, и, возможно, оно будет работать так, как вы ожидаете:

text.tag_add("marg", "1.0", "end")

К сожалению, вы потеряете это, если удалите весь текст в виджете, но это можно обойти.

1
Bryan Oakley 13 Мар 2018 в 17:33