события Python GUI вышли из строя

1
from Tkinter import *
from tkMessageBox import *

class Gui:
 def __init__(self, root):
  self.container = Frame(root)
  self.container.grid()
  self.inputText = Text(self.container, width=50, height=8)
  self.outputText = Text(self.container, width=50, height=8, bg='#E0E0E0', state=DISABLED)
  self.inputText.grid(row=0, column=0)
  self.outputText.grid(row=0, column=1)

  self.inputText.bind("<Key>", self.translate)

 def translate(self, event):
  input  = self.inputText.get(0.0, END)
  output = self.outputText.get(0.0, END)

  self.outputText.config(state=NORMAL)
  self.outputText.delete(0.0, END)
  self.outputText.insert(INSERT, input)
  self.outputText.config(state=DISABLED)

  showinfo(message="Input: %s characters\nOutput: %s characters" % (len(input), len(input)))


root = Tk()   #toplevel object
app = Gui(root)  #call to the class where gui is defined
root.mainloop()  #enter event loop

Работа с gui в tkinter. Я немного запутался в последовательности, в которой запускаются обработчики событий. Если вы запустите вышеуказанный код, вы, надеюсь, увидите...

1) Редактирование текстового виджета запускает обработчик событий, но, похоже, он отключает его, не регистрируя фактическое изменение, 2) Даже когда текстовый виджет очищается (т.е. Продолжает нажимать BackSpace), он все еще имеет одну строку длины символа, 3) Выходной виджет получает свое обновление только при запуске триггера события NEXT, несмотря на то, что данные пришли к предыдущему событию.

Является ли это тем, как привязки работают в tkinter или я что-то здесь не вижу?

Поведение, которое я бы хотел, при обновлении входного виджета: 1) Покажите изменение, 2) Введите обработчик событий, 3) Обновите виджет вывода, 4) Показать окно сообщения.

Теги:
user-interface
tkinter
events

1 ответ

4
Лучший ответ

Вот как работают привязки (и это хорошо), но ваша проблема легко решена.

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

  • если есть привязка непосредственно к виджету, он будет запущен перед любыми другими привязками.
  • если есть привязка к классу виджетов, он запускается следующий
  • если есть привязка к виджетам верхнего уровня, содержащему виджет, он запускается следующим образом (обратите внимание: в этом контексте окно корневого окна рассматривается как окно верхнего уровня).
  • если есть привязка на "все", он будет срабатывать следующим образом.

Последовательность может быть остановлена ​​в любой точке одним из обработчиков событий, но это рядом с точкой для этого конкретного обсуждения.

В случае по умолчанию привязка к <Key> происходит до привязки класса, и это привязка класса, где текст фактически вставлен в виджет. Вот почему ваша привязка всегда кажется одним символом.

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

Вы можете поменять порядок привязок, чтобы сначала связать класс. Или добавьте дополнительный привязку в свой текстовый виджет и добавьте его в последовательность после привязки класса и привяжите к нему. Обычно добавление bindtag - лучшее решение, но не всегда.

Чтобы изменить bindtags, вы можете сделать что-то вроде этого:

self.inputText.bindtags(((str(self.inputText)), "Text", "post-insert", ".", "all"))

Чтобы привязываться к "post-insert", сделайте это с помощью метода bind_class:

self.inputText.bind_class("post-insert", "<Key>", self.translate)

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

Кстати, не забывайте, что если вы получите все символы до конца текстового виджета, в конце будет всегда добавлена ​​новая строка. Либо перейдите в end-1c, либо обрезайте одну новую строку из текста.

  • 0
    Спасибо, что нашли время напечатать это Брайан, объясняет много.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню