Получение _tkinter.TclError, когда я пытаюсь вырезать и вставить в пользовательское текстовое поле tkinter - PullRequest
0 голосов
/ 21 ноября 2018

Я работаю над текстовым редактором, использующим tkinter в python 3. У меня проблема с классом пользовательских текстовых полей, который я использую для привязки номеров строк.От ответа Брайана Окли на этот вопрос .Вот код для класса:

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

Вот код для функции вырезания:

def cutSelected(event=None):
    textField.event_generate("<<Cut>>")

...

# Add cut to the edit menu in the menu bar
editMenu.add_command(label = "Cut", command = cutSelected, accelerator = "Ctrl+X")

...

# setting up the keyboard shortcut for the cut function
textField.bind("<Control-x>", cutSelected)
textField.bind("<Control-X>", cutSelected)

Вот код для функции вставки:

def paste(event=None):
    textField.event_generate("<<Paste>>")

...

# Add paste to the edit menu in the menu bar
editMenu.add_command(label = "Paste", command = paste, accelerator = "Ctrl+V")

...

# setting up the keyboard shortcut for the paste function
textField.bind("<Control-v>", paste)
textField.bind("<Control-V>", paste)

Вот трассировка ошибки (кроме учетных данных из путей):

Traceback (most recent call last):
  File "C:\Users\me\mydocuments\Programming\myeditor\main.py", line 457, in <module>
    root.mainloop()
  File "C:\Users\me\AppData\Local\Programs\Python\Python37- 
32\lib\tkinter\__init__.py", line 1283, in mainloop
    self.tk.mainloop(n)
  File "C:\Users\me\mydocuments\Programming\myeditor\main.py", line 58, in _proxy
    result = self.tk.call(cmd)
_tkinter.TclError: text doesn't contain any characters tagged with "sel"

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

Вырезание работает очень хорошо, когда я делаю это изменю редактирования, но когда я пытаюсь вырезать текст с помощью сочетания клавиш, я получаю сообщение об ошибке.

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

1 Ответ

0 голосов
/ 21 ноября 2018

_tkinter.TclError: текст не содержит символов, помеченных как "sel"

Не думаю, что у меня есть исправление, но у меня есть что-то, что мешает вашему кодуот сбоя.

Замените это:

result = self.tk.call(cmd)

... этим:

try:
    result = self.tk.call(cmd)
except Exception:
    return None

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

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

Вероятно, он делает это дважды, потому что tkinter уже имеет привязку по умолчанию для вырезания и вставки.Вероятно, происходит то, что ваша привязка срабатывает, а затем запускается встроенная привязка.Если вы хотите, чтобы встроенная привязка не вступила в силу, вам нужно вернуть "break" из paste.Я только догадываюсь на данный момент, так как вы не предоставили [mcve] для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...