Обработка TclError в событии выбора текста, вызванном прокси-сервером вызова - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь использовать событие Selection в текстовом виджете с модификациями, аналогичными решению Брайана Окли (прокси-сервер должен быть там для другой функции). В обратном вызове события мне нужно получить индекс sel.last, пока кнопка все еще нажата, чтобы получить выбор в «реальном времени»:

import tkinter as tk                                                                                                           
                                                                                                                           
class T(tk.Text):                                                                                                              
    def __init__(self, *args, **kwargs):                                                                                       
        tk.Text.__init__(self, *args, **kwargs)                                                                                
                                                                                                                           
        self._orig = self._w + "_orig"                                                                                         
        self.tk.call("rename", self._w, self._orig)                                                                            
        self.tk.createcommand(self._w, self._proxy)                                                                            
                                                                                                                           
        self.bind('<<Selection>>', self._on_selection)                                                                         
                                                                                                                           
    def _proxy(self, *args):                                                                                                   
                                                                                                                           
        cmd = (self._orig,) + args                                                                                             
        print("cmd: " + str(cmd))                                                                                              
                                                                                                                                                                                                                                            
        return self.tk.call(cmd)                                                                                               
                                                                                                                           
    def _on_selection(self, event):                                                                                            
        print(self.index('sel.last'))                                                                                          
                                                                                                                           
root = tk.Tk()                                                                                                                 
text = T()                                                                                                                     
text.pack()                                                                                                                    
text.insert(tk.END, 'asdf' * 20)                                                                                               
root.mainloop()

Приложение вылетает с необработанным исключением на второй щелчок (или выделение) в текстовом виджете (поскольку выделение удаляется на кнопке-1 перед запросом в выделении):

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

Теперь исключение не может быть устранено путем обработки его в выделении Обратный вызов события, поскольку исключение выбрасывается в основном l oop. Простое решение - изменить метод _proxy и добавить там обработку исключений к чувствительному вызову:

    def _proxy(self, *args):                                                                                                   
                                                                                                                           
        cmd = (self._orig,) + args                                                                                             
        print("cmd: " + str(cmd))                                                                                              
                                                                                                                           
        if args[0] == 'index' and args[1] == 'sel.last':                                                                       
            try:                                                                                                               
                return self.tk.call(cmd)                                                                                       
            except:                                                                                                            
                return None                                                                                                    
        else:                                                                                                                  
            return self.tk.call(cmd)

Мои два вопроса:

  1. Мое решение кажется немного хакерским (и не слишком крепкий); есть ли более элегантный способ обработать исключение дальше «вниз» по стеку (в случае события)?
  2. Как я могу проверить (используя функцию tkinter) в обратном вызове Selection, доступен ли sel.last или нет?

1 Ответ

0 голосов
/ 11 июля 2020

Наконец я понял, что мне не обязательно использовать тег 'sel.last', чтобы получить фактический выбор перед выпуском Button-1; Вместо этого я могу использовать «вставить», поскольку курсор автоматически перемещается вместе с мышью, когда кнопка нажата. Таким образом, я ответил на свой второй вопрос, что делает первый вопрос ненужным (или, по крайней мере, откладывает его).

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