Найти в Дзене
programmer's notes (python and more)

Программирование на языке Python. Графика PyQt5. Продолжение с графическим редактированием

Доброго здоровья читателям моего канала programmer's notes. Поддерживаем мой канал.

Объекты QPixmap и QImage в PyQt5

Изучив ещё раз раз свой канал, я совершенно чётко увидел несколько тем, которые освящены плохо. Конечно это графика. Хотя статьи по графике и есть. Но, как минимум, по трём библиотекам желательно добавить статьи. Сегодня будет продолжение графики вот этой статьи. В ней показан один из возможных алгоритмов рисования с помощью мыши. Естественно возникает вопрос: а как сохранить картинку, которую вы нарисовали. Я несколько переделал алгоритм, но идеологию оставил прежнюю. Поэтому мне пришлось несколько подстраиваться под эту идеологию. По этой причине объект класса QImage будет использоваться, как вспомогательный, а не основной инструмент. Но в будущем я рассмотрю и другой вариант подобного "редактора". Конечно, это очень простой редактор, но мне важна идея, а её можно развивать. Указанную выше статью, надо бы посмотреть, хотя сегодняшнюю программу, я постараюсь тоже хорошо прокомментировать. Да, нужно вспомнить про стандартные диалоговые окна. Например, почитать в моей статье здесь.

Программа, которая представлена ниже, проста (см. Рисунок 2). Двойной щелчок мыши и можно рисовать. Ещё один двойной щелчок - выход из режима рисования. Ctrl+s - сохранить рисунок в указанный файл.

Программа представлена ниже, см. Рисунок 1.

Рисунок 1. Скриншот текста программы. Сам текст можно получить по ссылке ниже
Рисунок 1. Скриншот текста программы. Сам текст можно получить по ссылке ниже
primer391.py

Пояснения к программе

  • Список self.vcp хранит точки, определяющие нарисованную линию. Каждый элемент массива состоит из трех компонент: две координаты и признак того, что это последняя точка непрерывной линии (значение 0, не последняя точка, значение 1 - последняя).
  • Переменная self.f равна 1, если мышью можно рисовать и 0, если рисовать нельзя.
  • Идея редактора заключается в том, что при движении мыши в режиме рисования точки, по которым проходит курсор мыши, заносятся в массив self.vcp и сразу вызывается процедура paintEvent() для перерисовки. Для этого используется метод self.update().
  • В процедуре paintEvent() создаётся объект класса QPainter, основного класса для рисования. Далее создаётся перо setPen() с указанием ширины и цвета (QColor()). Само рисование происходит между методами begin() и end(). Рисование в нашем случае заключается в соединении соседних точек (метод drawLine()) по всему массиву self.vcp.
  • Метод mouseMoveEvent() отслеживает движение мыши и если self.f равен 1, заносить координаты в массив self.vcp.
  • Метод mouseDoubleClickEvent() срабатывает при двойном щелчке левой кнопкой мыши. Происходит переключение из состояния рисования в состояние не рисования и обратно. Если мы выходим из состояния рисования, то помечаем последнюю точку, чтобы от неё потом не шла линия.
  • Метод mouseReleaseEvent() срабатывает, когда отпускается клавиша мыши. В программе отрабатывается отпускание правой кнопки мыши. Из массива self.vcp удаляется последняя точка, а новая последняя точка помечается как последняя. Для перерисовки вызывается метод update(). При этом учитываем, в каком состоянии находится программа, если в состоянии рисования, то нажатие не учитывается.
  • Для сохранения изображения используется сочетание ctrl+s. Для этого применяется метод keyPressEvent(). Проверяется нажата ли s и потом нажат ли ctrl. Также учитывается значение self.f. При нажатии вызывается метод self.sv().
  • Для получения имени файла, куда нужно будет сохранить картинку, используем класс QFileDialog и метод getSaveFileName().
  • Далее интересное. С помощью метода grab() получаем пиксельную копию окна (объект класса QPixmap). Далее с помощью метода toImage() получаем объект класса QImage. После чего уже можно создавать файл-картинку с помощью метода save().
Рисунок 2. Окно программы
Рисунок 2. Окно программы

Замечание 1.
Подход, представленный в программе не слишком хорош. Мы работаем со всем окном, а там надо разместить и меню и кнопки. Это мешает сделать из программы полноценный графический редактор. Поэтому в будущем мы посмотрим, как усовершенствовать подход, если использовать в окне объект QImage.

Замечание 2.
Ещё один важный момент. По сути мы используем так называем векторный подход, т.е. храним изображения в виде последовательности объектов (в нашем случае точек). Но сохраняем через QImage весь образ окна. Рациональнее было бы хранить всё в виде файла-содержащего массив self.vcp. И к этому вопросу мы тоже вернёмся в одной из
следующих статей.

Пока всё!

Хорошего программирования. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.

Что пользы от ваших рисунков, если их не сохранить
Что пользы от ваших рисунков, если их не сохранить