FishHookВсе верно, но не учли несколько маленьких ньюансов:
1. .bind хорош только с event, а Вы его задушили :) Для простого действия кнопки лучше использовать command…
2. Можно self.b2.pack(side= “left”)
3. Зачем создавать root и при этом наследовать рамку? Если root не будет передан, рамка сама для себя его построит, т.е.
root = Tk()
app = Application(master=root)
Равнозначно
Вот если бы вы меняли размеры окна или производили с ним другие управляющие действия - вот тогда сам бог велел использовать root, хотя и от этого можно уйти, ведь у рамки (self в нашем случае) есть параметр - .master, который ссылается непосредственно на корневое окно.
4. Не очень хорошая практика назначения одного параметра через обращению к элементу списка, т.е. желательно было бы (хотя и не обязательно)
лучше вставить в процесс создания экземпляра класса, т.е.
self.b1 = Button(self, text="1")
Имеет смысл использовать такой способ замены свойства виджета, когда нужно его изменить и только его. В противном случае рационально использовать метод .config или .configure :)
5. Зачем использовать askokcancel. В Вашем случае лучше будет showinfo…
6. И последнее. Этого делать никак нельзя:
app.mainloop()
root.destroy()
Как можно после обработчика событий “забивать” главное окно? Окончание работы обработчика - это и есть закрытие главного окна. Вы пытаетесь его повторно грохнуть. tcl вываливает, естественно, ошибку :)