Как получить доступ к нарисованному QPainter?
Пишу на Python программу, которая выводит на QLabel фотографию при помощи QPainter.drawPixmap, чтобы потом рисовать на ней мышью произвольные каляки-маляки (закрашенные полигоны).
Конечная задача состоит в том, чтобы посчитать площадь закрашенных красным полигонов:
Не нашёл варианта лучше, чем тупо пересчитать пиксели определённого цвета.
Подскажите пожалуйста, каким образом можно получить доступ к художествам, нарисованным QPainter.
Привожу код класса MegaLabel, который я сделал, чтобы реализовать обработку нажатия и выделения мышью над QLabel:
# This Python file uses the following encoding: utf-8
from PyQt5 import QtWidgets
from PyQt5.QtGui import QPixmap, QPainter, QPolygon, QPen, QBrush
from PyQt5.QtCore import Qt
class MegaLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super(MegaLabel, self).__init__(parent=parent)
self.selected_line = [] # отдельный выделенный пользлвателем полигон
self.selected_lines = [] # массив всех полигонов
self.image = QPixmap() # картинка, на фоне которой происходит рисование
self.scale_factor = 1.0 # отношение размера отображаемой картинки к реальному
def paintEvent(self, event):
painter = QPainter(self)
if not self.image.isNull(): # отображение фоновой картинки
painter.drawPixmap(self.rect(), self.image)
painter.setPen(QPen(Qt.red, 5, Qt.SolidLine))
painter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
# Отрисовка всех уже залитых полигонов
for i in range(len(self.selected_lines)): # преобразование координат от 1:1 к отображаемым
transformed_line = [j * self.scale_factor for j in self.selected_lines[i]]
painter.drawPolygon(QPolygon(transformed_line))
# Отображение линии в процессе рисования
transformed_line = [j * self.scale_factor for j in self.selected_line] # преобразование координат от 1:1 к отображаемым
painter.drawPolyline(QPolygon(transformed_line))
def mousePressEvent(self, event): # при нажатии левой кнопкой начинают записываться координаты нового полигона
if event.buttons() & Qt.LeftButton:
self.selected_line = []
def mouseMoveEvent(self, event): # при нажатой кнопке происходит запись координат
if event.buttons() & Qt.LeftButton:
# Координаты выделения приводятся к координатам фонового рисунка в масштабе 1:1
self.selected_line.append(event.pos() / self.scale_factor)
self.update()
def mouseReleaseEvent(self, event): # при отпускании кнопки список координат полигона передаётся в массив полигонов
if event.button() & Qt.LeftButton:
self.selected_lines.append(self.selected_line)
self.update()
Ответы (1 шт):
В итоге всё решилось отрисовкой на QImage, которая потом отрисовывалась на QLabel, код при этом упростился:
from PyQt5 import QtWidgets
from PyQt5.QtGui import QPainter, QPolygon, QPen, QBrush, QImage
from PyQt5.QtCore import Qt
class MegaLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super(MegaLabel, self).__init__(parent=parent)
self.selected_line = [] # координаты полигона
self.image = QImage() # картинка, на которой происходит рисование
self.scale_factor = 1.00 # отношение размера отображаемой картинки к реальному
def paintEvent(self, event):
painter = QPainter(self)
if not self.image.isNull():
painter.drawImage(self.rect(), self.image)
def mousePressEvent(self, event): # при нажатии левой кнопкой начинают записываться координаты нового полигона
if event.buttons() & Qt.LeftButton:
self.selected_line = []
def mouseMoveEvent(self, event): # при нажатой кнопке происходит запись координат
if event.buttons() & Qt.LeftButton:
impainter = QPainter(self.image) # QPainter для image
self.selected_line.append(event.pos() / self.scale_factor) # Координаты выделения приводятся к координатам фонового рисунка в масштабе 1:1
impainter.setPen(QPen(Qt.red, 5, Qt.SolidLine))
impainter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
impainter.drawPolyline(QPolygon(self.selected_line))
self.update()
def mouseReleaseEvent(self, event): # при отпускании кнопки список координат полигона передаётся в массив полигонов
if event.button() & Qt.LeftButton:
impainter = QPainter(self.image) # QPainter для image
impainter.setPen(QPen(Qt.red, 5, Qt.SolidLine))
impainter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
impainter.drawPolygon(QPolygon(self.selected_line))
self.update()
QImage поддерживает требуемые операции, в том числе, на ней можно пересчитать пиксели требуемого цвета.
