Beispiel #1
0
def qwtDrawStar1Symbols(painter, points, numPoints, symbol):
    size = symbol.size()
    painter.setPen(symbol.pen())
    sqrt1_2 = np.sqrt(0.5)
    r = QRectF(0, 0, size.width(), size.height())
    for pos in points:
        r.moveCenter(pos.toPoint())
        c = QPointF(r.center())
        d1 = r.width() / 2.0 * (1.0 - sqrt1_2)
        painter.drawLine(r.left() + d1, r.top() + d1, r.right() - d1, r.bottom() - d1)
        painter.drawLine(r.left() + d1, r.bottom() - d1, r.right() - d1, r.top() + d1)
        painter.drawLine(c.x(), r.top(), c.x(), r.bottom())
        painter.drawLine(r.left(), c.y(), r.right(), c.y())
Beispiel #2
0
    def _check_area(self):
        """
        Check if the current layout added areas cover the entire rectangle.

        Rectangle given by the extreme points for the added areas.
        """
        self._area_rects = []
        height = self._rows + 1
        area_float_rects = []
        delta = 0.0001
        for index, area in enumerate(self._areas):
            # These areas are used with a small delta to ensure if they are
            # next to each other they will not overlap.
            rectf = QRectF()
            rectf.setLeft(area["column"] + delta)
            rectf.setRight(area["column"] + area["col_span"] - delta)
            rectf.setTop(height - area["row"] - delta)
            rectf.setBottom(height - area["row"] - area["row_span"] + delta)
            rectf.index = index
            rectf.plugin_ids = area["plugin_ids"]
            area_float_rects.append(rectf)

            # These areas are used to calculate the actual total area
            rect = QRectF()
            rect.setLeft(area["column"])
            rect.setRight(area["column"] + area["col_span"])
            rect.setTop(height - area["row"])
            rect.setBottom(height - area["row"] - area["row_span"])
            rect.index = index
            rect.plugin_ids = area["plugin_ids"]

            self._area_rects.append(rect)

        # Check if areas are overlapping!
        for rect_1 in area_float_rects:
            for rect_2 in area_float_rects:
                if rect_1.index != rect_2.index:
                    if rect_1.intersects(rect_2):
                        raise SpyderAPIError(
                            "Area with plugins {0} is overlapping area "
                            "with plugins {1}".format(rect_1.plugin_ids,
                                                      rect_2.plugin_ids))

        # Check the total area (using corner points) versus the sum of areas
        total_area = 0
        tops = []
        rights = []
        for index, rect in enumerate(self._area_rects):
            tops.append(rect.top())
            rights.append(rect.right())
            area = abs(rect.width() * rect.height())
            total_area += area
            self._areas[index]["area"] = area

        if total_area != max(rights)*max(tops):
            raise SpyderAPIError(
                "Areas are not covering the entire section!\n"
                "Either an area is missing or col_span/row_span are "
                "not correctly set!"
            )
Beispiel #3
0
    def colorBarRect(self, rect):
        """
        Calculate the the rectangle for the color bar

        :param QRectF rect: Bounding rectangle for all components of the scale
        :return: Rectangle for the color bar
        """
        cr = QRectF(rect)
        if self.__data.scaleDraw.orientation() == Qt.Horizontal:
            cr.setLeft(cr.left() + self.__data.borderDist[0])
            cr.setWidth(cr.width() - self.__data.borderDist[1] + 1)
        else:
            cr.setTop(cr.top() + self.__data.borderDist[0])
            cr.setHeight(cr.height() - self.__data.borderDist[1] + 1)
        sda = self.__data.scaleDraw.alignment()
        if sda == QwtScaleDraw.LeftScale:
            cr.setLeft(cr.right() - self.__data.margin -
                       self.__data.colorBar.width)
            cr.setWidth(self.__data.colorBar.width)
        elif sda == QwtScaleDraw.RightScale:
            cr.setLeft(cr.left() + self.__data.margin)
            cr.setWidth(self.__data.colorBar.width)
        elif sda == QwtScaleDraw.BottomScale:
            cr.setTop(cr.top() + self.__data.margin)
            cr.setHeight(self.__data.colorBar.width)
        elif sda == QwtScaleDraw.TopScale:
            cr.setTop(cr.bottom() - self.__data.margin -
                      self.__data.colorBar.width)
            cr.setHeight(self.__data.colorBar.width)
        return cr
Beispiel #4
0
    def renderItem(self, painter, widget, rect, fillBackground):
        """
        Render a legend entry into a given rectangle.

        :param QPainter painter: Painter
        :param QWidget widget: Widget representing a legend entry
        :param QRectF rect: Bounding rectangle
        :param bool fillBackground: When true, fill rect with the widget background
        """
        if fillBackground:
            if widget.autoFillBackground() or widget.testAttribute(
                    Qt.WA_StyledBackground):
                QwtPainter.drawBackground(painter, rect, widget)
        label = widget  # TODO: cast to QwtLegendLabel
        if label is not None:
            icon = label.data().icon()
            sz = icon.defaultSize()
            iconRect = QRectF(
                rect.x() + label.margin(),
                rect.center().y() - 0.5 * sz.height(),
                sz.width(),
                sz.height(),
            )
            icon.render(painter, iconRect, Qt.KeepAspectRatio)
            titleRect = QRectF(rect)
            titleRect.setX(iconRect.right() + 2 * label.spacing())
            painter.setFont(label.font())
            painter.setPen(label.palette().color(QPalette.Text))
            label.drawText(painter,
                           titleRect)  # TODO: cast label to QwtLegendLabel
Beispiel #5
0
class HLine(ChartItem):
    """ Simple horizontal line without horizontal bounds.

    :param parent: Parent item.
    """
    def __init__(self, parent=None):
        super(HLine, self).__init__(parent)
        self.chartItemFlags = ChartItemFlags.FLAG_NO_AUTO_RANGE

        self._y = None
        self._label = None

        self._pen = QPen(QBrush(Qt.green), 1.0, Qt.SolidLine)
        self._pen.setCosmetic(True)
        self._brush = QBrush(QColor(255, 255, 255, 0))

        finfo = np.finfo(np.float32)
        self.b_rect = QRectF(finfo.min / 2.0, 0, finfo.max, 0)

    @property
    def label(self):
        return self._label

    def setY(self, y, label=None, color=QColor(Qt.red)):
        """ Sets the Hline's y value

        :param y: Ordinate value
        :param label:
        :param color:
        """
        self._y = y
        self.setPos(QPointF(0, self._y))

        if label is not None:
            self._label = label

        self._color = color
        self._pen = QPen(QBrush(color), 1.0, Qt.SolidLine)
        self._pen.setCosmetic(True)
        self._brush = QBrush(QColor(255, 255, 255, 0))

    def visibleRangeChanged(self, rect):
        b = min(rect.left(), rect.right())
        self.b_rect = QRectF(b - 10, 0, rect.width() + 20, 0)
        self.prepareGeometryChange()

    def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None):
        # p.setRenderHint(QPainter.N)
        p.setPen(self._pen)
        p.setBrush(self._brush)
        p.drawLine(
            QLineF(QPointF(self.b_rect.left(), 0),
                   QPointF(self.b_rect.right(), 0)))
        super(HLine, self).paint(p, o, widget)

    def __del__(self):
        _log.debug("Finalize HLine {}".format(self))
Beispiel #6
0
 def setCornerRects(self, path):
     pos = QPointF(0.0, 0.0)
     for i in range(path.elementCount()):
         el = path.elementAt(i)
         if el.type in (QPainterPath.MoveToElement, QPainterPath.LineToElement):
             pos.setX(el.x)
             pos.setY(el.y)
         elif el.type == QPainterPath.CurveToElement:
             r = QRectF(pos, QPointF(el.x, el.y))
             self.clipRects += [r.normalized()]
             pos.setX(el.x)
             pos.setY(el.y)
         elif el.type == QPainterPath.CurveToDataElement:
             if self.clipRects:
                 r = self.clipRects[-1]
                 r.setCoords(
                     min([r.left(), el.x]),
                     min([r.top(), el.y]),
                     max([r.right(), el.x]),
                     max([r.bottom(), el.y]),
                 )
                 self.clipRects[-1] = r.normalized()
Beispiel #7
0
    def minLabelDist(self, font):
        """
        Determine the minimum distance between two labels, that is necessary
        that the texts don't overlap.

        :param QFont font: Font
        :return: The maximum width of a label

        .. seealso::

            :py:meth:`getBorderDistHint()`
        """
        if not self.hasComponent(QwtAbstractScaleDraw.Labels):
            return 0

        ticks = self.scaleDiv().ticks(QwtScaleDiv.MajorTick)
        if not ticks:
            return 0

        fm = QFontMetrics(font)
        vertical = self.orientation() == Qt.Vertical

        bRect1 = QRectF()
        bRect2 = self.labelRect(font, ticks[0])
        if vertical:
            bRect2.setRect(-bRect2.bottom(), 0.0, bRect2.height(),
                           bRect2.width())

        maxDist = 0.0

        for tick in ticks:
            bRect1 = bRect2
            bRect2 = self.labelRect(font, tick)
            if vertical:
                bRect2.setRect(-bRect2.bottom(), 0.0, bRect2.height(),
                               bRect2.width())

            dist = fm.leading()
            if bRect1.right() > 0:
                dist += bRect1.right()
            if bRect2.left() < 0:
                dist += -bRect2.left()

            if dist > maxDist:
                maxDist = dist

        angle = qwtRadians(self.labelRotation())
        if vertical:
            angle += math.pi / 2

        sinA = math.sin(angle)
        if qFuzzyCompare(sinA + 1.0, 1.0):
            return math.ceil(maxDist)

        fmHeight = fm.ascent() - 2

        labelDist = fmHeight / math.sin(angle) * math.cos(angle)
        if labelDist < 0:
            labelDist = -labelDist

        if labelDist > maxDist:
            labelDist = maxDist

        if labelDist < fmHeight:
            labelDist = fmHeight

        return math.ceil(labelDist)
Beispiel #8
0
    def create_high_dpi_drop_indicator_pixmap(
            self, size: QSizeF, area: DockWidgetArea,
            mode: OverlayMode) -> QPixmap:
        '''
        Create high dpi drop indicator pixmap

        Parameters
        ----------
        size : QSizeF
        area : DockWidgetArea
        mode : OverlayMode

        Returns
        -------
        value : QPixmap
        '''
        border_color = self.icon_color(IconColor.frame_color)
        background_color = self.icon_color(IconColor.window_background_color)

        window = self.public.window()

        # QT version compatibility (TODO necessary for qtpy?)
        device_pixel_ratio = (window.devicePixelRatioF()
                              if hasattr(window, 'devicePixelRatioF')
                              else window.devicePixelRatio())

        pixmap_size = QSizeF(size * device_pixel_ratio)
        pm = QPixmap(pixmap_size.toSize())
        pm.fill(QColor(0, 0, 0, 0))
        p = QPainter(pm)
        pen = p.pen()
        shadow_rect = QRectF(pm.rect())

        base_rect = QRectF()
        base_rect.setSize(shadow_rect.size() * 0.7)
        base_rect.moveCenter(shadow_rect.center())

        # Fill
        shadow_color = self.icon_color(IconColor.shadow_color)
        if shadow_color.alpha() == 255:
            shadow_color.setAlpha(64)

        p.fillRect(shadow_rect, shadow_color)

        # Drop area rect.
        p.save()
        area_rect = QRectF()
        area_line = QLineF()
        non_area_rect = QRectF()

        if area == DockWidgetArea.top:
            area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width(),
                               base_rect.height()*.5)
            non_area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5,
                                   base_rect.width(), base_rect.height()*.5)
            area_line = QLineF(area_rect.bottomLeft(), area_rect.bottomRight())
        elif area == DockWidgetArea.right:
            area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(),
                               base_rect.width()*.5, base_rect.height())
            non_area_rect = QRectF(base_rect.x(), base_rect.y(),
                                   base_rect.width()*.5, base_rect.height())
            area_line = QLineF(area_rect.topLeft(), area_rect.bottomLeft())
        elif area == DockWidgetArea.bottom:
            area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5,
                               base_rect.width(), base_rect.height()*.5)
            non_area_rect = QRectF(base_rect.x(), base_rect.y(),
                                   base_rect.width(), base_rect.height()*.5)
            area_line = QLineF(area_rect.topLeft(), area_rect.topRight())
        elif area == DockWidgetArea.left:
            area_rect = QRectF(base_rect.x(), base_rect.y(),
                               base_rect.width()*.5, base_rect.height())
            non_area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(),
                                   base_rect.width()*.5, base_rect.height())
            area_line = QLineF(area_rect.topRight(), area_rect.bottomRight())

        baseSize = base_rect.size()
        if (OverlayMode.container == mode
                and area != DockWidgetArea.center):
            base_rect = area_rect

        p.fillRect(base_rect, background_color)
        if area_rect.isValid():
            pen = p.pen()
            pen.setColor(border_color)
            Color = self.icon_color(IconColor.overlay_color)
            if Color.alpha() == 255:
                Color.setAlpha(64)

            p.setBrush(Color)
            p.setPen(Qt.NoPen)
            p.drawRect(area_rect)
            pen = p.pen()
            pen.setWidth(1)
            pen.setColor(border_color)
            pen.setStyle(Qt.DashLine)
            p.setPen(pen)
            p.drawLine(area_line)

        p.restore()
        p.save()

        # Draw outer border
        pen = p.pen()
        pen.setColor(border_color)
        pen.setWidth(1)
        p.setBrush(Qt.NoBrush)
        p.setPen(pen)
        p.drawRect(base_rect)

        # draw window title bar
        p.setBrush(border_color)
        frame_rect = QRectF(base_rect.topLeft(),
                            QSizeF(base_rect.width(), baseSize.height()/10))
        p.drawRect(frame_rect)
        p.restore()

        # Draw arrow for outer container drop indicators
        if (OverlayMode.container == mode and
                area != DockWidgetArea.center):
            arrow_rect = QRectF()
            arrow_rect.setSize(baseSize)
            arrow_rect.setWidth(arrow_rect.width()/4.6)
            arrow_rect.setHeight(arrow_rect.height()/2)
            arrow_rect.moveCenter(QPointF(0, 0))

            arrow = QPolygonF()
            arrow.append(arrow_rect.topLeft())
            arrow.append(QPointF(arrow_rect.right(), arrow_rect.center().y()))
            arrow.append(arrow_rect.bottomLeft())

            p.setPen(Qt.NoPen)
            p.setBrush(self.icon_color(IconColor.arrow_color))
            p.setRenderHint(QPainter.Antialiasing, True)
            p.translate(non_area_rect.center().x(), non_area_rect.center().y())
            if area == DockWidgetArea.top:
                p.rotate(-90)
            elif area == DockWidgetArea.right:
                ...
            elif area == DockWidgetArea.bottom:
                p.rotate(90)
            elif area == DockWidgetArea.left:
                p.rotate(180)

            p.drawPolygon(arrow)

        pm.setDevicePixelRatio(device_pixel_ratio)
        return pm
Beispiel #9
0
    def boundingRect(self):
        """
        Calculate the bounding rectangle for a symbol at position (0,0).

        :return: Bounding rectangle
        """
        rect = QRectF()
        pinPointTranslation = False
        if self.__data.style in (QwtSymbol.Ellipse, QwtSymbol.Rect,
                                 QwtSymbol.Hexagon):
            pw = 0.0
            if self.__data.pen.style() != Qt.NoPen:
                pw = max([self.__data.pen.widthF(), 1.0])
            rect.setSize(self.__data.size + QSizeF(pw, pw))
            rect.moveCenter(QPointF(0.0, 0.0))
        elif self.__data.style in (
                QwtSymbol.XCross,
                QwtSymbol.Diamond,
                QwtSymbol.Triangle,
                QwtSymbol.UTriangle,
                QwtSymbol.DTriangle,
                QwtSymbol.RTriangle,
                QwtSymbol.LTriangle,
                QwtSymbol.Star1,
                QwtSymbol.Star2,
        ):
            pw = 0.0
            if self.__data.pen.style() != Qt.NoPen:
                pw = max([self.__data.pen.widthF(), 1.0])
            rect.setSize(QSizeF(self.__data.size) + QSizeF(2 * pw, 2 * pw))
            rect.moveCenter(QPointF(0.0, 0.0))
        elif self.__data.style == QwtSymbol.Path:
            if self.__data.path.graphic.isNull():
                self.__data.path.graphic = qwtPathGraphic(
                    self.__data.path.path, self.__data.pen, self.__data.brush)
            rect = qwtScaleBoundingRect(self.__data.path.graphic,
                                        self.__data.size)
            pinPointTranslation = True
        elif self.__data.style == QwtSymbol.Pixmap:
            if self.__data.size.isEmpty():
                rect.setSize(self.__data.pixmap.pixmap.size())
            else:
                rect.setSize(self.__data.size)
            pinPointTranslation = True
        elif self.__data.style == QwtSymbol.Graphic:
            rect = qwtScaleBoundingRect(self.__data.graphic.graphic,
                                        self.__data.size)
            pinPointTranslation = True
        elif self.__data.style == QwtSymbol.SvgDocument:
            if self.__data.svg.renderer is not None:
                rect = self.__data.svg.renderer.viewBoxF()
            if self.__data.size.isValid() and not rect.isEmpty():
                sz = QSizeF(rect.size())
                sx = self.__data.size.width() / sz.width()
                sy = self.__data.size.height() / sz.height()
                transform = QTransform()
                transform.scale(sx, sy)
                rect = transform.mapRect(rect)
            pinPointTranslation = True
        else:
            rect.setSize(self.__data.size)
            rect.moveCenter(QPointF(0.0, 0.0))
        if pinPointTranslation:
            pinPoint = QPointF(0.0, 0.0)
            if self.__data.isPinPointEnabled:
                pinPoint = rect.center() - self.__data.pinPoint
            rect.moveCenter(pinPoint)
        r = QRect()
        r.setLeft(np.floor(rect.left()))
        r.setTop(np.floor(rect.top()))
        r.setRight(np.floor(rect.right()))
        r.setBottom(np.floor(rect.bottom()))
        if self.__data.style != QwtSymbol.Pixmap:
            r.adjust(-1, -1, 1, 1)
        return r
Beispiel #10
0
    def activate(self, plot, plotRect, options=0x00):
        """
        Recalculate the geometry of all components.
        
        :param qwt.plot.QwtPlot plot: Plot to be layout
        :param QRectF plotRect: Rectangle where to place the components
        :param options: Layout options
        """
        self.invalidate()
        rect = QRectF(plotRect)
        self.__data.layoutData.init(plot, rect)
        if (not (options & self.IgnoreLegend) and plot.legend()
                and not plot.legend().isEmpty()):
            self.__data.legendRect = self.layoutLegend(options, rect)
            region = QRegion(rect.toRect())
            rect = region.subtracted(QRegion(
                self.__data.legendRect.toRect())).boundingRect()
            if self.__data.legendPos == QwtPlot.LeftLegend:
                rect.setLeft(rect.left() + self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.RightLegend:
                rect.setRight(rect.right() - self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.TopLegend:
                rect.setTop(rect.top() + self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.BottomLegend:
                rect.setBottom(rect.bottom() - self.__data.spacing)

        #     +---+-----------+---+
        #     |       Title       |
        #     +---+-----------+---+
        #     |   |   Axis    |   |
        #     +---+-----------+---+
        #     | A |           | A |
        #     | x |  Canvas   | x |
        #     | i |           | i |
        #     | s |           | s |
        #     +---+-----------+---+
        #     |   |   Axis    |   |
        #     +---+-----------+---+
        #     |      Footer       |
        #     +---+-----------+---+

        #  title, footer and axes include text labels. The height of each
        #  label depends on its line breaks, that depend on the width
        #  for the label. A line break in a horizontal text will reduce
        #  the available width for vertical texts and vice versa.
        #  expandLineBreaks finds the height/width for title, footer and axes
        #  including all line breaks.

        dimTitle, dimFooter, dimAxes = self.expandLineBreaks(options, rect)
        if dimTitle > 0:
            self.__data.titleRect.setRect(rect.left(), rect.top(),
                                          rect.width(), dimTitle)
            rect.setTop(self.__data.titleRect.bottom() + self.__data.spacing)
            if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled !=
                    self.__data.layoutData.scale[QwtPlot.yRight].isEnabled):
                self.__data.titleRect.setX(rect.left() +
                                           dimAxes[QwtPlot.yLeft])
                self.__data.titleRect.setWidth(rect.width() -
                                               dimAxes[QwtPlot.yLeft] -
                                               dimAxes[QwtPlot.yRight])
        if dimFooter > 0:
            self.__data.footerRect.setRect(rect.left(),
                                           rect.bottom() - dimFooter,
                                           rect.width(), dimFooter)
            rect.setBottom(self.__data.footerRect.top() - self.__data.spacing)
            if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled !=
                    self.__data.layoutData.scale[QwtPlot.yRight].isEnabled):
                self.__data.footerRect.setX(rect.left() +
                                            dimAxes[QwtPlot.yLeft])
                self.__data.footerRect.setWidth(rect.width() -
                                                dimAxes[QwtPlot.yLeft] -
                                                dimAxes[QwtPlot.yRight])
        self.__data.canvasRect.setRect(
            rect.x() + dimAxes[QwtPlot.yLeft],
            rect.y() + dimAxes[QwtPlot.xTop],
            rect.width() - dimAxes[QwtPlot.yRight] - dimAxes[QwtPlot.yLeft],
            rect.height() - dimAxes[QwtPlot.xBottom] - dimAxes[QwtPlot.xTop],
        )
        for axis in QwtPlot.AXES:
            if dimAxes[axis]:
                dim = dimAxes[axis]
                scaleRect = self.__data.scaleRect[axis]
                scaleRect.setRect(*self.__data.canvasRect.getRect())
                if axis == QwtPlot.yLeft:
                    scaleRect.setX(self.__data.canvasRect.left() - dim)
                    scaleRect.setWidth(dim)
                elif axis == QwtPlot.yRight:
                    scaleRect.setX(self.__data.canvasRect.right())
                    scaleRect.setWidth(dim)
                elif axis == QwtPlot.xBottom:
                    scaleRect.setY(self.__data.canvasRect.bottom())
                    scaleRect.setHeight(dim)
                elif axis == QwtPlot.xTop:
                    scaleRect.setY(self.__data.canvasRect.top() - dim)
                    scaleRect.setHeight(dim)
                scaleRect = scaleRect.normalized()

        #       +---+-----------+---+
        #       |  <-   Axis   ->   |
        #       +-^-+-----------+-^-+
        #       | | |           | | |
        #       |   |           |   |
        #       | A |           | A |
        #       | x |  Canvas   | x |
        #       | i |           | i |
        #       | s |           | s |
        #       |   |           |   |
        #       | | |           | | |
        #       +-V-+-----------+-V-+
        #       |   <-  Axis   ->   |
        #       +---+-----------+---+

        #  The ticks of the axes - not the labels above - should
        #  be aligned to the canvas. So we try to use the empty
        #  corners to extend the axes, so that the label texts
        #  left/right of the min/max ticks are moved into them.

        self.alignScales(options, self.__data.canvasRect,
                         self.__data.scaleRect)
        if not self.__data.legendRect.isEmpty():
            self.__data.legendRect = self.alignLegend(self.__data.canvasRect,
                                                      self.__data.legendRect)