Текст не содержит символов с тегом «sel» tkinter

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

Когда я пытался работать с этим кодом, он работал правильно, пока я не скопировал или не вставил что-то, то есть не нажал Ctrl+C или Ctrl+V. Он закрыл окно tkinter со следующей ошибкой:

_tkinter.TclError: text doesn't contain any characters tagged with "sel"

Вот код:

import tkinter as tk

class TextLineNumbers(tk.Canvas):
    def __init__(self, *args, **kwargs):
        tk.Canvas.__init__(self, *args, **kwargs)
        self.textwidget = None

    def attach(self, text_widget):
        self.textwidget = text_widget

    def redraw(self, *args):
        '''redraw line numbers'''
        self.delete("all")

        i = self.textwidget.index("@0,0")
        while True :
            dline= self.textwidget.dlineinfo(i)
            if dline is None: break
            y = dline[1]
            linenum = str(i).split(".")[0]
            self.create_text(2,y,anchor = "nw", text=linenum)
            i = self.textwidget.index("%s+1line" % i)

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, *args):
        # let the actual widget perform the requested action
        cmd = (self._orig,) + args
        result = self.tk.call(cmd)

        # generate an event if something was added or deleted,
        # or the cursor position changed
        if (args[0] in ("insert", "replace", "delete") or
            args[0:3] == ("mark", "set", "insert") or
            args[0:2] == ("xview", "moveto") or
            args[0:2] == ("xview", "scroll") or
            args[0:2] == ("yview", "moveto") or
            args[0:2] == ("yview", "scroll")
        ):
            self.event_generate("<<Change>>", when = "tail")

        # return what the actual widget returned
        return result

class Example(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.text = CustomText(self)
        self.vsb = tk.Scrollbar(orient = "vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.text.tag_configure("bigfont", font=("Helvetica", "24", "bold"))
        self.linenumbers = TextLineNumbers(self, width=30)
        self.linenumbers.attach(self.text)

        self.vsb.pack(side = "right", fill = "y")
        self.linenumbers.pack(side = "left", fill = "y")
        self.text.pack(side = "right", fill = "both", expand=True)

        self.text.bind("<<Change>>", self._on_change)
        self.text.bind("<Configure>", self._on_change)

        self.text.insert("end", "one\ntwo\nthree\n")
        self.text.insert("end", "four\n")
        self.text.insert("end", "five\n")

    def _on_change(self, event):
        self.linenumbers.redraw()

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side = "top", fill = "both", expand=True)
    root.mainloop()

Здесь: stackoverflow.com/questions/53417668/…

JacksonPro 10.12.2020 14:03
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
1
801
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

def _proxy(self, command, *args):
    # avoid error when copying
    if command == 'get' and (args[0] == 'sel.first' and args[1] == 'sel.last') and not textArea.tag_ranges('sel'): return

    # avoid error when deleting
    if command == 'delete' and (args[0] == 'sel.first' and args[1] == 'sel.last') and not textArea.tag_ranges('sel'): return

    cmd = (self._orig, command) + args
    result = self.tk.call(cmd)

    if command in ('insert', 'delete', 'replace'):
                self.event_generate('<<TextModified>>')

    return result

Другие вопросы по теме