Пример #1
0
class MarkerFactory(QObject):
    """
    Parameters
    ------------
    shape: Shape
        See config.Shape

    color: str, QColor
        Color of the marker. Marker must be filled and outlined with the
        same color.

    size: int
        Width and height of the output QGraphicsItem

    filled: bool
        Whether to fill the item.
    """
    _shape_to_class = EnumDict([(Shape.CIRCLE, EllipseMarker),
                                (Shape.DIAMOND, DiamondMarker)])

    def __init__(self, shape=Shape.CIRCLE, color=Qt.red, size=3, filled=True):
        super().__init__()
        self._brush = QBrush()
        self._pen = QPen()

        self.set_marker_shape(shape)
        self.set_marker_size(size)
        self.set_marker_color(color)
        self.set_marker_fill(filled)

    def get_marker_color(self) -> QColor:
        return self._pen.color()

    def set_marker_color(self, color: Union[QColor, int]):
        # XXX: what's the difference between settning alpha to 0 and
        # passing Qt.NoBrush to the constructor?
        # filled = deepcopy(self._brush.style())
        self._pen.setColor(color)
        self._brush.setColor(color)
        # self._brush.setStyle(filled)

    def get_marker_fill(self) -> bool:
        return bool(self._brush.style())

    def set_marker_fill(self, f: bool):
        if f:
            style = Qt.SolidPattern
        else:
            style = Qt.NoBrush
        self._brush.setStyle(style)

    def get_marker_shape(self) -> Shape:
        return self._shape

    def set_marker_shape(self, shape: Shape):
        self._shape = shape

    def get_marker_size(self):
        return self._size

    def set_marker_size(self, size: int):
        self._size = size

    def __call__(self, x: float, y: float, **kwargs: Any) -> Marker:
        """
        Create a Marker with the properties specified by this Factory.

        Parameters
        ------------
        x : float
        y : float
            X, Y coordinates of the marker.

        key : int
            Index that this marker will have in the parent VGraphicsGroup.
        """
        marker = TunableMarker(self._shape, self._size, key=None, **kwargs)
        marker.set_marker_color(self.get_marker_color())
        marker.set_marker_fill(self.get_marker_fill())
        # marker = self._marker_class(self._size, **kwargs)
        # marker.setBrush(self._brush)
        # marker.setPen(self._pen)
        marker.setPos(x, y)
        return marker
Пример #2
0
class TunableMarker(QGraphicsItem):
    def __init__(self,
                 shape: Shape,
                 size: int,
                 key: Optional[int] = None,
                 **kwargs):
        super().__init__()
        self._shape = shape
        self._size = size
        self.key = key
        self.info = kwargs

        self._pen = QPen()
        self._pen.setWidthF(0.25)
        self._brush = QBrush()

    def _make_rect(self, length):
        # make a rectangle of width and height equal to 'length' and centered
        # about (0, 0)
        return QRectF(-length / 2, -length / 2, length, length)

    def boundingRect(self):
        return self._make_rect(self._size + 4)

    def _paint_ellipse(self, painter):
        rect = self._make_rect(self._size)
        painter.drawEllipse(rect)

    def _paint_diamond(self, painter):
        size = self._size
        X = [0, size / 2, 0, -size / 2, 0]
        Y = [size / 2, 0, -size / 2, 0, size / 2]
        points = [QPointF(x, y) for x, y in zip(X, Y)]
        polygon = QPolygonF(points)
        painter.drawPolygon(polygon, len(points))

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem,
              widget: QWidget):

        painter.setPen(self._pen)
        painter.setBrush(self._brush)

        shape_to_paint_method = {
            Shape.CIRCLE: self._paint_ellipse,
            Shape.DIAMOND: self._paint_diamond
        }
        drawing_method = shape_to_paint_method[self._shape]
        drawing_method(painter)

    def get_marker_color(self):
        """
        Marker color.
        """
        return self._pen.color()

    def set_marker_color(self, color: Union[QColor, int]):
        color = QColor(color)
        self._pen.setColor(color)
        self._brush.setColor(color)
        self.update()

    def get_marker_fill(self) -> bool:
        """
        Whether this marker is filled in or merely an outline.
        """
        return bool(self._brush.style())

    def set_marker_fill(self, f: bool):
        if f:
            f = Qt.SolidPattern
        else:
            f = Qt.NoBrush
        self._brush.setStyle(f)
        self.update()

    def get_marker_shape(self):
        return self._shape

    def set_marker_shape(self, shape: Shape):
        self._shape = shape
        self.update()

    def get_marker_size(self):
        return self._size

    def set_marker_size(self, sz: int):
        self._size = sz
        self.update()