Глава 18 · Проект: приложение для рисования

Я закончил рисовать! Первая полная программа

Последние штрихи первого прототипа — очистка холста и свободное рисование — и работающая программа целиком.

Я закончил рисовать!

Осталось добавить кнопку очистки холста и режим «свободного рисования» (карандаш) — для него точки рисуются на каждое движение мыши без привязки к начальной точке:

ochistka_i_svobodno.py
def ochistit_holst():
    canvas.delete("all")

def vo_vremya_risovaniya(event):
    if tekuschaya_figura == "svobodno":
        canvas.create_oval(
            event.x - tolschina, event.y - tolschina,
            event.x + tolschina, event.y + tolschina,
            fill=tekuschij_cvet, outline=tekuschij_cvet,
        )
        return
    # ... остальные фигуры, как в разделе 18.5
Реальный холст: штрих из отдельных кружков с заметными промежутками между ними
Реальный холст: кружок на каждое движение мыши — при резком жесте между ними видны разрывы.
Отдельные кружки — не одна линия
Такой штрих рисует не непрерывную линию, а россыпь маленьких кружков-точек, которые иногда даже не соприкасаются друг с другом, если мышь двигалась быстро между двумя событиями <B1-Motion>. Раздел 18.14 показывает, как получить настоящий непрерывный штрих — соединяя каждую новую точку с предыдущей.

Первая полная программа

Полная версия первого прототипа, включая исправленную отрисовку «черновых» фигур во время перетаскивания мыши, доступна отдельным файлом:

projects/tkinter/paint-app/paint_app_basic.py

Реальное окно: холст с несколькими линиями, прямоугольником и овалом разных цветов — первый прототип рисовалки
Реальное окно первого прототипа: несколько фигур разных цветов на одном холсте.
Честная, но не окончательная версия
Мы построили настоящую работающую программу — с холстом, фигурами, цветом и толщиной. Но состояние здесь по-прежнему живёт в глобальных переменных, «отменить» ничего нельзя, а «черновая» фигура во время перетаскивания просто удаляется и создаётся заново. Начиная со следующего раздела глава смотрит на Canvas куда внимательнее: что он на самом деле хранит, как отменить действие по-настоящему и как вырастить из этого прототипа приложение уровня PaintApp (раздел 18.32).
★★ Самостоятельная задача
Кнопка «Отменить»

Сохраняйте id каждой нарисованной фигуры (canvas.create_* возвращает id) в список — и добавьте кнопку, удаляющую последнюю через canvas.delete(id). Раздел 18.24 разберёт эту идею как настоящую архитектуру.

★★★ Задача повышенной сложности
Сохранение рисунка

Изучите модуль tkinter.filedialog и попробуйте добавить кнопку «Сохранить» — как минимум сохраняющую список нарисованных фигур в текстовый файл (глава 15). Раздел 18.30 покажет полное решение через JSON.

Практика: первая полная программа
Модуль tkinter открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально
Открыть практику →

Итоги раздела

Что мы узнали

  • Canvas — виджет Tkinter для рисования линий и фигур по координатам; координаты растут вправо и вниз от левого верхнего угла.
  • canvas.create_line/rectangle/oval(...) рисуют готовые фигуры по координатам.
  • События мыши (<Button-1>, <B1-Motion>, <ButtonRelease-1>) отслеживают клик, перетаскивание и отпускание кнопки мыши.
  • Scale — ползунок для выбора числа в диапазоне.
  • Палитра из нескольких похожих кнопок эффективнее строится циклом, чем вручную одна за другой.
  • Это только первый прототип — дальше глава разбирает Canvas и архитектуру приложения куда внимательнее.