В Tkinter привязать действие к виджету

Реализую игру "Магический шар", используя библиотеку Tkinter в стандартном пакете Python. Написал код окна и виджетов в нем:

  • область для написания вопросов (на основе tk.Text) + кнопка "Спросить"
  • область для вывода ответов (также tk.Text)
  • область tk.Text для написания новых вариантов ответов (здесь мы как бы "обучаем" шар).

Функционал простой и, конечно, следом потребует доработки (выход из игры, обновление области вопросы и ответов, простой анализ на основе регулярных выражений - скажем, чтобы игра видела знак вопроса в конце вопросительного предложения). Функции (обработчики событий):

  • список ответов
  • приглашение задать вопрос и его "обдумывание" + случайный ответ (пока так, но следом случайный ответ перенесу в отдельную функцию для области ответов)
  • далее напишу функцию обработки новых вопросов.

Работаю в среде Jupyter Notebook. Испытал проблемы:

  1. если ставлю обработку ввода текста print(event.char), то вывод полученного от пользователя текста осуществляется в консоль Jupyter, а не в окно программы. Как сделать обратное? Причем если пишу функцию просто для вывода текста с одной приведенной строкой, то вывод идет туда и туда, но тогда дальнейшая логика в обработчике отсутствует.
  2. заданный функцией диалог с пользователем ("Задайте свой вопрос: ") также отправляется в консоль.

Таким образом, питон tkinter видит события в виджете текста, но после их обработки результат дает в консоль.

Код:

# Функция задает вопрос пользователю, а затем возвращает случайные результаты из ответов
def answerQuery(event):
#     print(event.char)
    question = input("Прошу Вас - задайте свой вопрос: ")
    print("Я заглядываю за повороты судьбы, чтобы узнать о грядущем")
    time.sleep(2)
    print("Хмм...")
    time.sleep(2)
    print(random.choice(responses))  # responses - список ответов

# Связывает событие нажатия клавиши с answerQuery()
# text_box_question - область tk.Text для написания вопросов
text_box_question.bind('<Key>', answerQuery)

Ответы (1 шт):

Автор решения: GrAnd

Читайте текст из вашего виджета:

question = text_box_question.get("1.0", END)

И выводите в другой:

text_box_answer.insert(END, "Хмм..." + "\n")
wnd.update_idletasks()
time.sleep(2)
text_box_answer.insert(END, random.choice(responses) + "\n")

Но лучше sleep() не использовать. Этим вы заблочите весь UI (будет казаться, что программа 'зависла'). Вместо этого можно использовать метод after() (отложенное исполнение кода). Например так:

wnd.after(2000, lambda: text_box_answer.insert(END, random.choice(responses) + "\n"))
→ Ссылка