Я пытаюсь использовать событие 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)
Мои два вопроса:
- Мое решение кажется немного хакерским (и не слишком крепкий); есть ли более элегантный способ обработать исключение дальше «вниз» по стеку (в случае события)?
- Как я могу проверить (используя функцию tkinter) в обратном вызове Selection, доступен ли sel.last или нет?