def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent): box = QRectF(self.buttonDownRect) pos = event.pos() offset = pos - event.buttonDownPos(Qt.LeftButton) if self.handleSelected is None: box.translate(offset) new_box = box elif self.handleSelected == 0: pos = box.topLeft() + offset new_size = box.bottomRight() - pos width = max(new_size.x(), 0) height = max(new_size.y(), 0) left = min(pos.x(), box.right()) top = min(pos.y(), box.bottom()) new_box = QRectF(left, top, width, height) elif self.handleSelected == 1: pos = box.topLeft() + offset height = max(box.bottom() - pos.y(), 0) top = min(pos.y(), box.bottom()) new_box = QRectF(box.left(), top, box.width(), height) elif self.handleSelected == 2: pos = box.topRight() + offset top = min(pos.y(), box.bottom()) width = max(pos.x() - box.left(), 0) height = max(box.bottom() - pos.y(), 0) new_box = QRectF(box.left(), top, width, height) elif self.handleSelected == 3: pos = box.topRight() + offset width = max(pos.x() - box.left(), 0) new_box = QRectF(box.left(), box.top(), width, box.height()) elif self.handleSelected == 4: pos = box.bottomRight() + offset new_size = pos - box.topLeft() width = max(new_size.x(), 0) height = max(new_size.y(), 0) new_box = QRectF(box.left(), box.top(), width, height) elif self.handleSelected == 5: pos = box.bottomRight() + offset height = max(pos.y() - box.top(), 0) new_box = QRectF(box.left(), box.top(), box.width(), height) elif self.handleSelected == 6: pos = box.bottomLeft() + offset left = min(pos.x(), box.right()) width = max(box.right() - pos.x(), 0) height = max(pos.y() - box.top(), 0) new_box = QRectF(left, box.top(), width, height) elif self.handleSelected == 7: pos = box.bottomLeft() + offset left = min(pos.x(), box.right()) width = max(box.right() - pos.x(), 0) new_box = QRectF(left, box.top(), width, box.height()) new_box = QRectF(round(new_box.left()), round(new_box.top()), round(new_box.width()), round(new_box.height())) self.setRect(new_box) self.setHandlesPos() self.signalHandler.boxChanged.emit(self.tabIndex, self.rowIndex, new_box)
def paste(self): data = {} try: data = json.loads(QGuiApplication.clipboard().text()) except Exception as e: return self.clear_selection() # calculate offset positions = [] for d in data['drawings']: positions.append({'x': d['pos x'], 'y': d['pos y']}) for n in data['nodes']: positions.append({'x': n['position x'], 'y': n['position y']}) offset_for_middle_pos = QPointF(0, 0) if len(positions) > 0: rect = QRectF(positions[0]['x'], positions[0]['y'], 0, 0) for p in positions: x = p['x'] y = p['y'] if x < rect.left(): rect.setLeft(x) if x > rect.right(): rect.setRight(x) if y < rect.top(): rect.setTop(y) if y > rect.bottom(): rect.setBottom(y) offset_for_middle_pos = self.last_mouse_move_pos - rect.center() self.undo_stack.push(Paste_Command(self, data, offset_for_middle_pos))
class Callout(QGraphicsItem): """ This class code was taken from \ https://code.qt.io/cgit/qt/qtcharts.git/tree/examples/charts/callout/callout.cpp?h=5.13 """ def __init__(self, chart): QGraphicsItem.__init__(self, chart) self.chart = chart self.rect = QRectF() self.anchor = QPointF() self.text_rect = QRectF() self.text = "" self.font = QFont() def boundingRect(self): anchor = self.mapFromParent(self.chart.mapToPosition(self.anchor)) rect = QRectF() rect.setLeft(min(self.rect.left(), anchor.x())) rect.setRight(max(self.rect.right(), anchor.x())) rect.setTop(min(self.rect.top(), anchor.y())) rect.setBottom(max(self.rect.bottom(), anchor.y())) return rect def paint(self, painter, option, widget): path = QPainterPath() path.addRoundedRect(self.rect, 5, 5) painter.setBrush(QColor(255, 255, 255)) painter.drawPath(path) painter.drawText(self.text_rect, self.text) def set_anchor(self, point): self.anchor = point def updateGeometry(self): self.prepareGeometryChange() self.setPos(self.chart.mapToPosition(self.anchor) + QPoint(10, -50)) def set_text(self, text): self.text = text metrics = QFontMetrics(self.font) self.text_rect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt.AlignLeft, self.text) self.text_rect.translate(5, 5) self.prepareGeometryChange() self.rect = QRectF(self.text_rect.adjusted(-5.0, -5.0, 5.0, 5.0))
def anchorPos(self, rect: QtCore.QRectF) -> QtCore.QPointF: if isinstance(self.anchor, QtCore.Qt.Corner): if self.anchor == QtCore.Qt.TopLeftCorner: pos = rect.topLeft() elif self.anchor == QtCore.Qt.TopRightCorner: pos = rect.topRight() elif self.anchor == QtCore.Qt.BottomLeftCorner: pos = rect.bottomLeft() else: # BottomRightCorner pos = rect.bottomRight() else: # AnchorPoint if self.anchor == QtCore.Qt.AnchorTop: pos = QtCore.QPointF(rect.center().x(), rect.top()) elif self.anchor == QtCore.Qt.AnchorLeft: pos = QtCore.QPointF(rect.left(), rect.center().y()) elif self.anchor == QtCore.Qt.AnchorRight: pos = QtCore.QPointF(rect.right(), rect.center().y()) elif self.anchor == QtCore.Qt.AnchorBottom: pos = QtCore.QPointF(rect.center().x(), rect.bottom()) else: raise ValueError( "Only Top, Left, Right, Bottom anchors supported.") return pos
class Callout(QGraphicsItem): """ This class code was taken from \ https://code.qt.io/cgit/qt/qtcharts.git/tree/examples/charts/callout/callout.cpp?h=5.13 """ def __init__(self, chart): QGraphicsItem.__init__(self, chart) self.chart = chart self.rect = QRectF() self.anchor = QPointF() self.text_rect = QRectF() self.text = "" self.font = QFont() def boundingRect(self): anchor = self.mapFromParent(self.chart.mapToPosition(self.anchor)) rect = QRectF() rect.setLeft(min(self.rect.left(), anchor.x())) rect.setRight(max(self.rect.right(), anchor.x())) rect.setTop(min(self.rect.top(), anchor.y())) rect.setBottom(max(self.rect.bottom(), anchor.y())) return rect def paint(self, painter, option, widget): path = QPainterPath() path.addRoundedRect(self.rect, 5, 5) anchor = self.mapFromParent(self.chart.mapToPosition(self.anchor)) if not self.rect.contains(anchor): point1 = QPointF() point2 = QPointF() # establish the position of the anchor point in relation to m_rect above = anchor.y() <= self.rect.top() aboveCenter = anchor.y() > self.rect.top() and anchor.y( ) <= self.rect.center().y() belowCenter = anchor.y() > self.rect.center().y() and anchor.y( ) <= self.rect.bottom() below = anchor.y() > self.rect.bottom() onLeft = anchor.x() <= self.rect.left() leftOfCenter = anchor.x() > self.rect.left() and anchor.x( ) <= self.rect.center().x() rightOfCenter = anchor.x() > self.rect.center().x() and anchor.x( ) <= self.rect.right() onRight = anchor.x() > self.rect.right() # get the nearest m_rect corner x = (onRight + rightOfCenter) * self.rect.width() y = (below + belowCenter) * self.rect.height() cornerCase = (above and onLeft) or (above and onRight) or ( below and onLeft) or (below and onRight) vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y) x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * ( not vertical) * (onLeft * 10 - onRight * 20) y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * ( above * 10 - below * 20) x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * ( not vertical) * (onLeft * 20 - onRight * 10) y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * ( above * 20 - below * 10) point1.setX(x1) point1.setY(y1) point2.setX(x2) point2.setY(y2) path.moveTo(point1) path.lineTo(anchor) path.lineTo(point2) path = path.simplified() painter.setBrush(QColor(255, 255, 255)) painter.drawPath(path) painter.drawText(self.text_rect, self.text) def set_anchor(self, point): self.anchor = point def updateGeometry(self): self.prepareGeometryChange() self.setPos(self.chart.mapToPosition(self.anchor) + QPoint(10, -50)) def set_text(self, text): self.text = text metrics = QFontMetrics(self.font) self.text_rect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt.AlignLeft, self.text) self.text_rect.translate(5, 5) self.prepareGeometryChange() self.rect = QRectF(self.text_rect.adjusted(-5.0, -5.0, 5.0, 5.0))
class Callout(QGraphicsItem): def __init__(self, chart): QGraphicsItem.__init__(self, chart) self._chart = chart self._text = "" self._textRect = QRectF() self._anchor = QPointF() self._font = QFont() self._rect = QRectF() def boundingRect(self): anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) rect = QRectF() rect.setLeft(min(self._rect.left(), anchor.x())) rect.setRight(max(self._rect.right(), anchor.x())) rect.setTop(min(self._rect.top(), anchor.y())) rect.setBottom(max(self._rect.bottom(), anchor.y())) return rect def paint(self, painter, option, widget): path = QPainterPath() path.addRoundedRect(self._rect, 5, 5) anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) if not self._rect.contains(anchor) and not self._anchor.isNull(): point1 = QPointF() point2 = QPointF() # establish the position of the anchor point in relation to _rect above = anchor.y() <= self._rect.top() aboveCenter = (anchor.y() > self._rect.top() and anchor.y() <= self._rect.center().y()) belowCenter = (anchor.y() > self._rect.center().y() and anchor.y() <= self._rect.bottom()) below = anchor.y() > self._rect.bottom() onLeft = anchor.x() <= self._rect.left() leftOfCenter = (anchor.x() > self._rect.left() and anchor.x() <= self._rect.center().x()) rightOfCenter = (anchor.x() > self._rect.center().x() and anchor.x() <= self._rect.right()) onRight = anchor.x() > self._rect.right() # get the nearest _rect corner. x = (onRight + rightOfCenter) * self._rect.width() y = (below + belowCenter) * self._rect.height() cornerCase = ((above and onLeft) or (above and onRight) or (below and onLeft) or (below and onRight)) vertical = abs(anchor.x() - x) > abs(anchor.y() - y) x1 = (x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * int(not vertical) * (onLeft * 10 - onRight * 20)) y1 = (y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20)) point1.setX(x1) point1.setY(y1) x2 = (x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * int(not vertical) * (onLeft * 20 - onRight * 10)) y2 = (y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10)) point2.setX(x2) point2.setY(y2) path.moveTo(point1) path.lineTo(anchor) path.lineTo(point2) path = path.simplified() painter.setBrush(QColor(255, 255, 255)) painter.drawPath(path) painter.drawText(self._textRect, self._text) def mousePressEvent(self, event): event.setAccepted(True) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: self.setPos( mapToParent(event.pos() - event.buttonDownPos(Qt.LeftButton))) event.setAccepted(True) else: event.setAccepted(False) def setText(self, text): self._text = text metrics = QFontMetrics(self._font) self._textRect = QRectF( metrics.boundingRect(QRect(0.0, 0.0, 150.0, 150.0), Qt.AlignLeft, self._text)) self._textRect.translate(5, 5) self.prepareGeometryChange() self._rect = self._textRect.adjusted(-5, -5, 5, 5) def setAnchor(self, point): self._anchor = QPointF(point) def updateGeometry(self): self.prepareGeometryChange() self.setPos(self._chart.mapToPosition(self._anchor) + QPointF(10, -50))
class activeMarker(QGraphicsPolygonItem): size = 10 triangle = QPolygonF() triangle.append(QPointF(-size, size)) triangle.append(QPointF(0, 0)) triangle.append(QPointF(size, size)) cross = QPolygonF() cross.append(QPointF(-size/2, -size/2)) cross.append(QPointF(0, 0)) cross.append(QPointF(size / 2, size / 2)) cross.append(QPointF(0, 0)) cross.append(QPointF(-size / 2, size / 2)) cross.append(QPointF(0, 0)) cross.append(QPointF(size / 2, -size / 2)) cross.append(QPointF(0, 0)) @classmethod def fromTriangle(cls, parent=None): color = QColor(255, 255, 255) item = activeMarker(parent=parent) item.setPolygon(cls.triangle) item.setPen(QPen(color)) item.setBrush(QBrush(color)) # set move range to parent bounding rect item.moveRange = item.parentItem().boundingRect().bottomRight() return item @classmethod def fromCross(cls, parent=None): color = QColor(0, 0, 0) item = activeMarker(parent=parent) item.setPolygon(cls.cross) item.setPen(QPen(color)) item.setBrush(QBrush(color)) # set move range to parent bounding rect item.moveRange = item.parentItem().boundingRect().bottomRight() return item def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.onMouseMove, self.onMouseRelease = lambda e, x, y: 0, lambda e, x, y: 0 self.moveRange = QRectF(0.0, 0.0, 0.0, 0.0) def setMoveRange(self, rect): self.moveRange = rect def mousePressEvent(self, e): pass def mouseMoveEvent(self, e): # position relative to parent pos = e.scenePos() - self.parentItem().scenePos() x, y = pos.x(), pos.y() # limit move to moveRange xmin, ymin = self.moveRange.left(), self.moveRange.top() xmax, ymax = self.moveRange.right(), self.moveRange.bottom() x, y = xmin if x < xmin else xmax if x > xmax else x, ymin if y < ymin else ymax if y > ymax else y self.setPos(x, y) self.onMouseMove(e, x, y) def mouseReleaseEvent(self, e): # position relative to parent pos = e.scenePos() - self.parentItem().scenePos() x, y = pos.x(), pos.y() # limit move to (0,0) and moveRange xmin, ymin = self.moveRange.left(), self.moveRange.top() xmax, ymax = self.moveRange.right(), self.moveRange.bottom() x, y = xmin if x < xmin else xmax if x > xmax else x, ymin if y < ymin else ymax if y > ymax else y self.onMouseRelease(e, x, y)
class Callout(QGraphicsItem): def __init__(self, chart): QGraphicsItem.__init__(self, chart) self._chart = chart self._text = "" self._textRect = QRectF() self._anchor = QPointF() self._font = QFont() self._rect = QRectF() def boundingRect(self): anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) rect = QRectF() rect.setLeft(min(self._rect.left(), anchor.x())) rect.setRight(max(self._rect.right(), anchor.x())) rect.setTop(min(self._rect.top(), anchor.y())) rect.setBottom(max(self._rect.bottom(), anchor.y())) return rect def paint(self, painter, option, widget): path = QPainterPath() path.addRoundedRect(self._rect, 5, 5) anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) if not self._rect.contains(anchor) and not self._anchor.isNull(): point1 = QPointF() point2 = QPointF() # establish the position of the anchor point in relation to _rect above = anchor.y() <= self._rect.top() aboveCenter = (anchor.y() > self._rect.top() and anchor.y() <= self._rect.center().y()) belowCenter = (anchor.y() > self._rect.center().y() and anchor.y() <= self._rect.bottom()) below = anchor.y() > self._rect.bottom() onLeft = anchor.x() <= self._rect.left() leftOfCenter = (anchor.x() > self._rect.left() and anchor.x() <= self._rect.center().x()) rightOfCenter = (anchor.x() > self._rect.center().x() and anchor.x() <= self._rect.right()) onRight = anchor.x() > self._rect.right() # get the nearest _rect corner. x = (onRight + rightOfCenter) * self._rect.width() y = (below + belowCenter) * self._rect.height() cornerCase = ((above and onLeft) or (above and onRight) or (below and onLeft) or (below and onRight)) vertical = abs(anchor.x() - x) > abs(anchor.y() - y) x1 = (x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * int(not vertical) * (onLeft * 10 - onRight * 20)) y1 = (y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20)) point1.setX(x1) point1.setY(y1) x2 = (x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * int(not vertical) * (onLeft * 20 - onRight * 10)) y2 = (y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10)) point2.setX(x2) point2.setY(y2) path.moveTo(point1) path.lineTo(anchor) path.lineTo(point2) path = path.simplified() painter.setBrush(QColor(255, 255, 255)) painter.drawPath(path) painter.drawText(self._textRect, self._text) def mousePressEvent(self, event): event.setAccepted(True) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: self.setPos(mapToParent( event.pos() - event.buttonDownPos(Qt.LeftButton))) event.setAccepted(True) else: event.setAccepted(False) def setText(self, text): self._text = text metrics = QFontMetrics(self._font) self._textRect = QRectF(metrics.boundingRect( QRect(0.0, 0.0, 150.0, 150.0),Qt.AlignLeft, self._text)) self._textRect.translate(5, 5) self.prepareGeometryChange() self._rect = self._textRect.adjusted(-5, -5, 5, 5) def setAnchor(self, point): self._anchor = QPointF(point) def updateGeometry(self): self.prepareGeometryChange() self.setPos(self._chart.mapToPosition( self._anchor) + QPointF(10, -50))
class activeMarker(QGraphicsPolygonItem): """ Movable marker """ size = 10 triangle = QPolygonF() triangle.append(QPointF(-size, size)) triangle.append(QPointF(0, 0)) triangle.append(QPointF(size, size)) cross = QPolygonF() cross.append(QPointF(-size / 2, -size / 2)) cross.append(QPointF(0, 0)) cross.append(QPointF(size / 2, size / 2)) cross.append(QPointF(0, 0)) cross.append(QPointF(-size / 2, size / 2)) cross.append(QPointF(0, 0)) cross.append(QPointF(size / 2, -size / 2)) cross.append(QPointF(0, 0)) @classmethod def fromTriangle(cls, *args, **kwargs): color = QColor(255, 255, 255) item = cls(*args, **kwargs) item.setPolygon(cls.triangle) item.setPen(QPen(color)) item.setBrush(QBrush(color)) # set move range to parent bounding rect item.moveRange = item.parentItem().boundingRect() return item @classmethod def fromCross(cls, *args, **kwargs): color = QColor(0, 0, 0) item = cls(*args, **kwargs) item.setPolygon(cls.cross) item.setPen(QPen(color)) item.setBrush(QBrush(color)) # set move range to parent bounding rect item.moveRange = item.parentItem().boundingRect() return item def __init__(self, parent=None): super().__init__(parent=parent) self.onMouseMove, self.onMouseRelease = lambda e, x, y: 0, lambda e, x, y: 0 self.moveRange = QRectF(0.0, 0.0, 0.0, 0.0) @property # read only def currentColor(self): return self.scene().slider2D.QImg.pixelColor( (self.pos() - self.parentItem().offset()).toPoint()) def setMoveRange(self, rect): self.moveRange = rect def mousePressEvent(self, e): pass def mouseMoveEvent(self, e): # event position relative to parent pos = e.pos() + self.pos( ) # e.scenePos() - self.parentItem().scenePos() # TODO modified 16/02/20 validate x, y = pos.x(), pos.y() # limit move to moveRange xmin, ymin = self.moveRange.left(), self.moveRange.top() xmax, ymax = self.moveRange.right(), self.moveRange.bottom() x, y = xmin if x < xmin else xmax if x > xmax else x, ymin if y < ymin else ymax if y > ymax else y self.setPos(x, y) self.onMouseMove(e, x, y) def mouseReleaseEvent(self, e): # event position relative to parent pos = e.pos() + self.pos( ) # e.scenePos() - self.parentItem().scenePos() x, y = pos.x(), pos.y() # limit move to (0,0) and moveRange xmin, ymin = self.moveRange.left(), self.moveRange.top() xmax, ymax = self.moveRange.right(), self.moveRange.bottom() x, y = xmin if x < xmin else xmax if x > xmax else x, ymin if y < ymin else ymax if y > ymax else y self.onMouseRelease(e, x, y)
def drawMagnifier(self): # First, calculate the magnifier position due to the mouse position watch_area_width = 16 watch_area_height = 16 cursor_pos = self.mousePoint watch_area = QRect( QPoint(cursor_pos.x() - watch_area_width / 2, cursor_pos.y() - watch_area_height / 2), QPoint(cursor_pos.x() + watch_area_width / 2, cursor_pos.y() + watch_area_height / 2)) if watch_area.left() < 0: watch_area.moveLeft(0) watch_area.moveRight(watch_area_width) if self.mousePoint.x( ) + watch_area_width / 2 >= self.screenPixel.width(): watch_area.moveRight(self.screenPixel.width() - 1) watch_area.moveLeft(watch_area.right() - watch_area_width) if self.mousePoint.y() - watch_area_height / 2 < 0: watch_area.moveTop(0) watch_area.moveBottom(watch_area_height) if self.mousePoint.y( ) + watch_area_height / 2 >= self.screenPixel.height(): watch_area.moveBottom(self.screenPixel.height() - 1) watch_area.moveTop(watch_area.bottom() - watch_area_height) # tricks to solve the hidpi impact on QCursor.pos() watch_area.setTopLeft( QPoint(watch_area.topLeft().x() * self.scale, watch_area.topLeft().y() * self.scale)) watch_area.setBottomRight( QPoint(watch_area.bottomRight().x() * self.scale, watch_area.bottomRight().y() * self.scale)) watch_area_pixmap = self.screenPixel.copy(watch_area) # second, calculate the magnifier area magnifier_area_width = watch_area_width * 10 magnifier_area_height = watch_area_height * 10 font_area_height = 40 cursor_size = 24 magnifier_area = QRectF( QPoint(QCursor.pos().x() + cursor_size, QCursor.pos().y() + cursor_size), QPoint(QCursor.pos().x() + cursor_size + magnifier_area_width, QCursor.pos().y() + cursor_size + magnifier_area_height)) if magnifier_area.right() >= self.screenPixel.width(): magnifier_area.moveLeft(QCursor.pos().x() - magnifier_area_width - cursor_size / 2) if magnifier_area.bottom( ) + font_area_height >= self.screenPixel.height(): magnifier_area.moveTop(QCursor.pos().y() - magnifier_area_height - cursor_size / 2 - font_area_height) # third, draw the watch area to magnifier area watch_area_scaled = watch_area_pixmap.scaled( QSize(magnifier_area_width * self.scale, magnifier_area_height * self.scale)) magnifier_pixmap = self.graphics_scene.addPixmap(watch_area_scaled) magnifier_pixmap.setOffset(magnifier_area.topLeft()) # then draw lines and text self.graphics_scene.addRect(QRectF(magnifier_area), QPen(QColor(255, 255, 255), 2)) self.graphics_scene.addLine( QLineF( QPointF(magnifier_area.center().x(), magnifier_area.top()), QPointF(magnifier_area.center().x(), magnifier_area.bottom())), QPen(QColor(0, 255, 255), 2)) self.graphics_scene.addLine( QLineF( QPointF(magnifier_area.left(), magnifier_area.center().y()), QPointF(magnifier_area.right(), magnifier_area.center().y())), QPen(QColor(0, 255, 255), 2)) # get the rgb of mouse point point_rgb = QColor(self.screenPixel.toImage().pixel(self.mousePoint)) # draw information self.graphics_scene.addRect( QRectF( magnifier_area.bottomLeft(), magnifier_area.bottomRight() + QPoint(0, font_area_height + 30)), QPen(Qt.black), QBrush(Qt.black)) rgb_info = self.graphics_scene.addSimpleText( ' Rgb: ({0}, {1}, {2})'.format(point_rgb.red(), point_rgb.green(), point_rgb.blue())) rgb_info.setPos(magnifier_area.bottomLeft() + QPoint(0, 5)) rgb_info.setPen(QPen(QColor(255, 255, 255), 2)) rect = self.selected_area.normalized() size_info = self.graphics_scene.addSimpleText( ' Size: {0} x {1}'.format(rect.width() * self.scale, rect.height() * self.scale)) size_info.setPos(magnifier_area.bottomLeft() + QPoint(0, 15) + QPoint(0, font_area_height / 2)) size_info.setPen(QPen(QColor(255, 255, 255), 2))