tkinter.simpledialog. Диалог оставляет инициатора tkinter.Button в депрессии
Я использую Python 3.3 на Windows 7. У меня есть tkinter
приложение, где один Button
разжигает tkinter.simpledialog.Dialog
, Вот так (это полный, работающий пример):
import tkinter
import tkinter.simpledialog
class Mainframe(tkinter.Frame):
def __init__(self, parent):
super(Mainframe, self).__init__(parent)
self.parent = parent
self.button = tkinter.Button(self, text="Open Dialog")
open_dialog_op = lambda ev: self.open_dialog(ev)
self.button.bind("<Button-1>", open_dialog_op)
self.button.bind("<Return>", open_dialog_op)
self.button.pack(side=tkinter.LEFT)
def open_dialog(self, event):
dialog = tkinter.simpledialog.Dialog(self.parent, "My Dialog")
self.button.config(relief=tkinter.RAISED) # does not help!
root = tkinter.Tk()
Mainframe(root).pack()
root.mainloop()
Поведение:
- если вы сосредоточены на "Открытый диалог"
Button
и наберите RETURN, все работает хорошо - если щелкнуть мышью
Button
, диалог появляется все хорошо, но - когда диалог закрывается, "Открыть диалог"
Button
показано в депрессивном состоянии (tkinter.SUNKEN
если я не ошибаюсь?) гос. - (Интересно, что когда диалог открыт,
Button
отображается нормально. Подавленный вид начинается только после закрытия диалога.) - Я попытался исправить проблему, просто позвонив
button.config(relief=tkinter.RAISED)
, но это, похоже, ничего не делает в этом случае.
(На самом деле мое полное приложение начинает показывать кнопку как нажатую сразу после ее нажатия, а не только после того, как диалоговое окно снова закрывается. Я нахожу это намного более логичным: simpledialog
локальный цикл событий захватывает все события, потому что simpledialog
модально; это может включать в себя <ButtonRelease-1>
событие мыши на кнопке?)
Вопросы:
- Почему это происходит?
- Почему поведение в моем полном приложении может отличаться?
- Как я могу избежать или восстановить оба?
2 ответа
Это происходит потому, что вы частично перекрываете привязки по умолчанию, которые делают правильно.
Если вы хотите, чтобы кнопка выполняла функцию при активации кнопки, правильный способ сделать это - добавить command
вариант с кнопкой. Причина, по которой я использую "активацию" вместо "нажатие", заключается в том, что, как показывает ваш код, существует несколько способов активировать кнопку в ТК: нажатия кнопок, возвратные нажатия, нажатия клавиш ускорения и т. Д.
Код, который вы написали, не заменяет довольно большой набор привязок по умолчанию. Ответ от iCodez правильно исправляет наиболее очевидные дефекты, но оставляя привязки по умолчанию в силе и используя command=
будет работать для случаев, которые вы не тестировали (например, работа только с клавиатуры).
У меня есть простое, обходное решение для третьего вопроса. Собственно, у вас самого был ответ в вашем посте. Измените эту строку:
self.button.bind("<Button-1>", open_dialog_op)
к этому:
self.button.bind("<ButtonRelease-1>", open_dialog_op)
Сейчас, open_dialog_op
связан с выпуском щелчка мыши. Значение simpledialog
откроется только после того, как кнопка вернется вверх (каково ее поведение).
Тем не менее, я также хотел бы сделать предложение. Почему бы не использовать tkinter.messagebox.askokcancel
за это? Это то же самое, что и системные подсказки Windows. Увидеть ниже:
tkinter.simpledialog.Dialog
диалог:
tkinter.messagebox.askokcancel
диалог: