Глава 18 · Canvas по-настоящему

Жизненный цикл жеста мыши

Рисование одной фигуры — это последовательность из трёх разных событий, а не одно.

Один жест, три события

Рисование одной фигуры мышью — это не одно событие, а последовательность из трёх разных типов, которые вместе образуют жест «нарисовать»:

<Button-1>
Нажали левую кнопку мыши
start_x, start_y
Запоминаем точку начала
↻ 0, 1 или много раз
<B1-Motion>
Мышь движется с зажатой кнопкой
coords() / create_line()
Обновляем превью или штрих
<ButtonRelease-1>
Кнопку отпустили
render_document()
Фиксируем фигуру или действие
press → drag (0, 1 или много раз) → release — один и тот же жест для карандаша, линии, прямоугольника и овала.
СобытиеКогда срабатывает
<Button-1>ровно один раз — в момент нажатия левой кнопки
<B1-Motion>много раз подряд, пока кнопка зажата и мышь движется
<ButtonRelease-1>ровно один раз — в момент отпускания кнопки
&lt;Motion&gt; — это НЕ &lt;B1-Motion&gt;
<Motion> срабатывает при ЛЮБОМ движении мыши над холстом — даже если ни одна кнопка не нажата. <B1-Motion> — только при движении с зажатой ЛЕВОЙ кнопкой. Перепутать их — частая причина, по которой рисование начинается без клика (раздел 18.31, Debug Lab).

Все нужные координаты приходят через тот же объект Event, что и в главе 17 — event.x, event.y. event.widget тоже доступен, хотя для одного холста он обычно и так очевиден.

Клик без перетаскивания — не забыть про этот случай

Что если пользователь нажал и сразу отпустил кнопку в одной точке, не подвинув мышь? <B1-Motion> в этом случае не произойдёт ни разу — событие сработает, только если мышь действительно сдвинулась. Финальное приложение (раздел 18.32) явно проверяет это: если точка начала и точка отпускания почти совпадают, линия, прямоугольник или овал попросту не создаётся — вместо невидимой фигуры нулевого размера.

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