Обратите внимание, что окно диалога выглядит в Windows 7 (на платформе, где сделан снимок с экрана) именно так, как и должно выглядеть. Повторюсь, что модуль tkinter обеспечивает внешний вид создаваемых элементов, характерный для той платформы, на которой запускается сценарий. Мы можем изменять самые разные аспекты графического интерфейса (например, цвет и шрифт, текст и ярлык в заголовке окна, помещать на кнопки изображения вместо текста), но одно из преимуществ использования модуля tkinter - в том, что нам необходимо будет изменять лишь те параметры, которые требуется изменить.
ООП при разработке графических интерфейсов
Все примеры реализации графического интерфейса, представленные до сих пор, имели вид самостоятельных сценариев, включающих функцию обработки событий. В крупных программах часто более полезно бывает оформить программный код, создающий графический интерфейс, в виде подкласса виджета Frame из библиотеки tkinter - контейнера для других виджетов. В примере 1.25 приводится переработанная версия предыдущего сценария с одной кнопкой, в которой графический интерфейс реализован в виде класса.
from tkinter import *
from tkinter.messagebox import showinfo
class MyGui(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
button = Button(self, text=’press’, command=self.reply) button.pack() def reply(self):
showinfo(title=’popup’, message=’Button pressed!’)
if__name__== ‘__main__’:
window = MyGui()
window.pack()
window.mainloop()
Обработчик событий от кнопки - это
from tkinter import * from tkinter102 import MyGui
# главное окно приложения mainwin = Tk()
Label(mainwin, text=__name__).pack()
# окно диалога popup = Toplevel()
Label(popup, text=’Attach’).pack(side=LEFT)
MyGui(popup).pack(side=RIGHT) # присоединить виджеты
mainwin.mainloop()
Этот сценарий присоединяет наш графический интерфейс с одной кнопкой к другому окну popup типа Toplevel, которое передается импортированному приложению через вызов конструктора, как родительский компонент (кроме того, вы получаете доступ к главному окну Tk - как будет показано позже, вы всегда сможете получить к нему доступ, независимо от того, создается оно явно или нет). На этот раз наш пакет виджетов, содержащий единственную кнопку, присоединяется к правому краю контейнера. Если запустить этот пример, вы увидите картину, изображенную на рис. 1.4, где кнопка с надписью press - это наш подкласс класса Frame.
Кроме того, так как наш графический интерфейс MyGui оформлен в виде класса, мы получаем возможность настраивать его за счет использования механизма наследования - достаточно просто определить подкласс, реализующий необходимые отличия. Например, можно изменить реализацию метода reply, чтобы он делал что-то особенное, как показано в примере 1.27.
from tkinter import mainloop
from tkinter.messagebox import showinfo
from tkinter102 import MyGui
class CustomGui(MyGui): # наследует метод __init__
def reply(self): # замещает метод reply
showinfo(title=’popup’, message=’Ouch!’)
if__name__== ‘__main__’:
CustomGui().pack()
mainloop()
Если запустить этот сценарий, он создаст то же главное окно с кнопкой, что и оригинальный класс MyGui. Но щелчок на кнопке сгенерирует иной ответ, как показано на рис. 1.5, потому что будет вызвана другая версия метода reply.
Несмотря на свою простоту, эти графические интерфейсы иллюстрируют несколько важных идей. Как будет показано далее в этой книге, использование приемов ООП, таких как наследование и присоединение в данных примерах, позволяет повторно использовать пакеты виджетов в наших программах - калькуляторы, текстовые редакторы и подобные им интерфейсы легко могут настраиваться и добавляться в дру-