Оконная графика в языке Python

Для языка Python разработано много разных модулей для программирования оконных приложений. В дистрибутиве языка Python для Windows представлен только один из них — это модуль tkinter. Он очень простой и удобный для программирования несложных приложений, что важно для начинающих программистов. Правда, можно отметить и его недостатки, которых лишены более продвинутые оконные библиотеки для Python'а — например, не реализовано сглаживание линий (antialiasing). Но мы будем использовать tkinter, поскольку только он представлен во всех дистрибутивах языка Python.

Для примера мы рассмотрим программу, которая по кликам мыши рисует треугольник и вписанную в него окружность: "triangle.py".

Программа начинается с импорта модуля tkinter (мы импортируем все описания из него). Также мы импортируем наши собственные классы R2Vector и R2Point, которые мы используем для решения разнообразных геометрических задач на плоскости R2. Эти классы представлены в модуле R2Graph:

from tkinter import *
from R2Graph import *

Программу мы оформим в виде функции main, которая будет вызываться при исполнении скрипта. Все описания и другие функции будут локализованы внутри функции main:

from tkinter import *
from R2Graph import *

def main():
    rootWindow = Tk()
    rootWindow.title("Triangle")
    rootWindow.geometry("800x600")

    . . .

    rootWindow.mainloop()

if __name__ == "__main__":
    main()

Работа функции main начинается с создания корневого окна с заголовком "Triangle" и начальным размером 800 на 600 пикселей:

    rootWindow = Tk()
    rootWindow.title("Triangle")
    rootWindow.geometry("800x600")
В левой верхней части окна будут расположены две кнопки "Clear" и "Draw", а ниже будет располагаться дочернее окно, в котором происходит рисование и обработка кликов мыши. На приведенном выше рисунке окно рисования светло-голубого цвета.

Размещение дочерних окон — Layout Manager

Управление расположением дочерних окон в модуле tkinter может выполняться с помощью трех различных менеджеров расположения: place, pack, grid. Мы будем использовать менеждер pack, который в отличие от place позвляет корректировать расположение и размеры дочерних окон при изменении размеров окна верхнего уровня. Опуская фрагменты кода, укажем только тот код, который отвечает за создание и расположение дочерних окон. Их три: кнопки drawButton, clearButton и область рисования drawArea. Для горизонтальной группировки двух кнопок в верхней полоске окна мы создаем еще одно прозрачное окно panel типа Frame. Окно panel будет дочерним для окна верхнего уровня rootWindow, а кнопки drawButton и clearButton — дочерними для окна panel:

    panel = Frame(rootWindow)
    drawArea = Canvas(rootWindow, bg="lightBlue")
    . . .
    clearButton = Button(panel, text="Clear", command=clear)
    . . .
    drawButton = Button(panel, text="Draw", command=drawTriangle)
    . . .
    panel.pack(fill=X, padx=4, pady=4);
    clearButton.pack(side=LEFT)
    drawButton.pack(side=LEFT)
    drawArea.pack(fill=BOTH, side=TOP, expand=True, padx=4, pady=4)

Рассмотрим подробнее команды, создающие окна. Строка

    panel = Frame(rootWindow)
создает прозрачное окно типа Frame, которое нам нужно лишь для правильного размещения кнопок, которые потом будут добавляться внутрь окна panel как дочерние окна. Здесь единственный параметр конструктора — это окно, которое будет родительским для создаваемого окна, в нашем случае это rootWindow.

Команда
    clearButton = Button(panel, text="Clear", command=clear)
создает кнопку clearButton с надписью "Clear". Родительским окном для нее будет окно panel. Ключевой параметр command задает функцию, которая будет вызываться при нажатии на эту кнопку — это функция clear. Аналогично создается кнопка drawButton:
    drawButton = Button(panel, text="Draw", command=drawTriangle)
Отметим, что дочерние окна создаются невидимыми, они появятся на экране только после того, как будет выполнен метод pack.

. . .