def paintEvent(self, a0: QPaintEvent) -> None:

        super().paintEvent(a0)
        painter = QPainter(self)
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing)
        rect = QRectF(self.margin, self.margin,
                      self.width() - self.margin * 2,
                      self.height() - 2 * self.margin)
        painter.setBrush(Qt.white)
        painter.setPen(Qt.white)
        painter.drawRect(rect)
        painter.restore()
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen()
        pen.setWidth(3)
        painter.setPen(pen)
        path = QPainterPath()
        height, width = rect.height() + self.margin, rect.width() + self.margin
        path.moveTo(self.margin, height)
        path.cubicTo(height * 0.5, width * 0.9, height * 0.9, width * 0.5,
                     height, self.margin)
        painter.drawPath(path)
        painter.restore()
Example #2
0
    def paintEvent(self, event):

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)

        side = min(self.width(), self.height())
        painter.scale(side / 32.0, side / 32.0)

        painter.setPen(Qt.NoPen)

        if not self.is_pressed:
            painter.setBrush(self.back_color)
        else:
            painter.setBrush(
                QColor(self.back_color.red() + 30,
                       self.back_color.green() + 30,
                       self.back_color.blue() + 30))

        painter.drawRoundedRect(QRect(0, 0, 32, 32), 8, 8)

        if self.is_checked:

            check_path = QPainterPath()
            check_path.moveTo(self.x1)
            check_path.lineTo(self.x2)
            check_path.lineTo(self.x3)

            pen = QPen(self.check_color, self.check_thick, Qt.SolidLine)
            painter.setPen(pen)

            painter.drawPath(check_path)
Example #3
0
    def paint(self,
              q_painter: 'QPainter',
              style_option_graphics_item: 'QStyleOptionGraphicsItem',
              widget: 'QWidget' = None):

        pen = QPen()
        pen.setColor(self.color)
        pen.setWidth(3)
        pen.setJoinStyle(Qt.MiterJoin)  # 让箭头变尖
        q_painter.setPen(pen)

        path = QPainterPath()

        point1 = self.start_port
        path.moveTo(self.start_port.center_pos)
        # for i in self.line_items:
        #     i.setPen(QColor(255, 0, 0))
        #     i.update()
        for p in self.center_points + [self.end_port]:
            pen.setWidth(3)
            q_painter.setPen(pen)
            path.lineTo(p.center_pos)
            q_painter.drawLine(QLineF(point1.center_pos, p.center_pos))
            arrow = self.draw_arrow(q_painter, point1.center_pos, p.center_pos)
            path.addPolygon(arrow)  # 将箭头添加到连线上
            point1 = p
Example #4
0
    def paintEvent(self, event):

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)
        if self.label_width <= 0:
            return

        painter.setPen(Qt.NoPen)
        if self.hover:
            painter.setBrush(
                QColor(self.back_color.red() + 30,
                       self.back_color.green() + 30,
                       self.back_color.blue() + 30))
        else:
            painter.setBrush(self.back_color)

        painter.drawRoundedRect(QRect(0, 0, self.width(), self.height()),
                                self.border_radius, self.border_radius)

        x1 = QPointF(self.label_width + float(self.height() / 3),
                     float(self.height() * 0.45))
        x2 = QPointF(
            self.label_width + float(self.height() * (0.66 + self.rate) / 2),
            float(self.height() * 0.55))
        x3 = QPointF(self.width() - float(self.height() / 3),
                     float(self.height() * 0.45))

        check_path = QPainterPath()
        check_path.moveTo(x1)
        check_path.lineTo(x2)
        check_path.lineTo(x3)

        pen = QPen(self.text_color, self.drop_thick, Qt.SolidLine)
        painter.setPen(pen)
        painter.drawPath(check_path)
 def drawValue(self, p: QPainter, baseRect: QRectF, value: float, delta: float):
     if value == self.m_min:
         return
     if self.m_barStyle == self.BarStyle.EXPAND:
         p.setBrush(self.palette().highlight())
         p.setPen(QPen(self.palette().shadow().color(), self.m_dataPenWidth))
         radius = (baseRect.height() / 2) / delta
         p.drawEllipse(baseRect.center(), radius, radius)
         return
     if self.m_barStyle == self.BarStyle.LINE:
         p.setPen(QPen(self.palette().highlight().color(), self.m_dataPenWidth))
         p.setBrush(Qt.NoBrush)
         if value == self.m_max:
             p.drawEllipse(baseRect.adjusted(self.m_outlinePenWidth / 2, self.m_outlinePenWidth / 2,
                                             -self.m_outlinePenWidth / 2, -self.m_outlinePenWidth / 2))
         else:
             arcLength = 360 / delta
             p.drawArc(baseRect.adjusted(self.m_outlinePenWidth / 2, self.m_outlinePenWidth / 2,
                                         -self.m_outlinePenWidth / 2, -self.m_outlinePenWidth / 2),
                       int(self.m_nullPosition * 16),
                       int(-arcLength * 16))
         return
     dataPath = QPainterPath()
     dataPath.setFillRule(Qt.WindingFill)
     if value == self.m_max:
         dataPath.addEllipse(baseRect)
     else:
         arcLength = 360 / delta
         dataPath.moveTo(baseRect.center())
         dataPath.arcTo(baseRect, self.m_nullPosition, -arcLength)
         dataPath.lineTo(baseRect.center())
     p.setBrush(self.palette().highlight())
     p.setPen(QPen(self.palette().shadow().color(), self.m_dataPenWidth))
     p.drawPath(dataPath)
Example #6
0
    def paint(self, p, opt, widget):

        # Enforce constraints on handles
        r2 = Point(np.cos(np.radians(self.thetacenter)),
                   np.sin(np.radians(self.thetacenter)))  # chi center direction vector
        # constrain innerhandle to be parallel to outerhandle, and shorter than outerhandle
        self.innerhandle.setPos(r2 * self.innerradius)
        # constrain widthhandle to be counter-clockwise from innerhandle
        widthangle = np.radians(self.thetawidth / 2 + self.thetacenter)
        widthv = Point(np.cos(widthangle), np.sin(widthangle)) if self.thetawidth > 0 else r2
        # constrain widthhandle to half way between inner and outerhandles
        self.widthhandle.setPos(widthv * (self.innerradius + self.outerradius) / 2)
        # constrain handles to base values
        self.outerhandle.setPos(r2 * self.outerradius)


        pen = self.currentPen
        pen.setColor(QColor(0, 255, 255))

        p.setPen(pen)

        r = self.boundingRect()
        # p.drawRect(r)
        p.setRenderHint(QPainter.Antialiasing)

        p.scale(r.width(), r.height())  # workaround for GL bug

        centerangle = self.innerhandle.pos().angle(Point(1, 0))
        startangle = centerangle - self.thetawidth / 2
        endangle = centerangle + self.thetawidth / 2

        r = QCircRectF(radius=0.5)
        if self.innerradius < self.outerradius and self.thetawidth > 0:
            p.drawArc(r, -startangle * 16, -self.thetawidth * 16)

        radius = self.innerradius / self.outerradius / 2
        r = QCircRectF()
        r.radius = radius

        if self.innerradius < self.outerradius and self.thetawidth > 0:
            p.drawArc(r, -startangle * 16, -self.thetawidth * 16)

        pen.setStyle(Qt.DashLine)
        p.setPen(pen)

        p.drawLine(QPointF(0., 0.), self.widthhandle.pos().norm() / 2)
        r1v = self.innerhandle.pos().norm()
        p.drawLine(QPointF(0., 0.),
                   (-1. * self.widthhandle.pos() + 2 * self.widthhandle.pos().dot(r1v) * r1v).norm() / 2)
        pen.setStyle(Qt.SolidLine)

        if self.innerradius < self.outerradius and self.thetawidth > 0:
            path = QPainterPath()
            path.moveTo((-1. * self.widthhandle.pos() + 2 * self.widthhandle.pos().dot(r1v) * r1v).norm() / 2)
            path.arcTo(r, -startangle, -self.thetawidth)  # inside
            path.lineTo(self.widthhandle.pos().norm() / 2)  # ? side
            path.arcTo(QCircRectF(radius=0.5), -endangle, self.thetawidth)  # outside
            path.lineTo((-1. * self.widthhandle.pos() + 2 * self.widthhandle.pos().dot(r1v) * r1v).norm() / 2)
            self.path = path
            p.fillPath(path, QBrush(QColor(0, 255, 255, 20)))
Example #7
0
    def drawStar(self, qp):
        """Draw a star in the preview pane.

        Parameters
        ----------
        qp: QPainter object
        """
        width = self.rect().width()
        height = self.rect().height()
        col = QColor(135, 206, 235)
        pen = QPen(col, self._value)
        pen.setJoinStyle(Qt.PenJoinStyle.MiterJoin)
        qp.setPen(pen)

        path = QPainterPath()

        # draw pentagram
        star_center_x = width / 2
        star_center_y = height / 2
        # make sure the star equal no matter the size of the qframe
        if width < height:
            # not taking it all the way to the edge so the star has room to grow
            radius_outer = width * 0.35
        else:
            radius_outer = height * 0.35

        # start at the top point of the star and move counter clockwise to draw the path.
        # every other point is the shorter radius (1/(1+golden_ratio)) of the larger radius
        golden_ratio = (1 + np.sqrt(5)) / 2
        radius_inner = radius_outer / (1 + golden_ratio)
        theta_start = np.pi / 2
        theta_inc = (2 * np.pi) / 10
        for n in range(11):
            theta = theta_start + (n * theta_inc)
            theta = np.mod(theta, 2 * np.pi)
            if np.mod(n, 2) == 0:
                # use radius_outer
                x = radius_outer * np.cos(theta)
                y = radius_outer * np.sin(theta)

            else:
                # use radius_inner
                x = radius_inner * np.cos(theta)
                y = radius_inner * np.sin(theta)

            x_adj = star_center_x - x
            y_adj = star_center_y - y + 3
            if n == 0:

                path.moveTo(x_adj, y_adj)
            else:
                path.lineTo(x_adj, y_adj)

        qp.drawPath(path)
Example #8
0
    def updatePosition(self, scene):
        path = QPainterPath()

        self.prepareGeometryChange()

        count = len(self._longitudes)
        if count > 0:
            x, y = scene.posFromLonLat(self._longitudes, self._latitudes)
            path.moveTo(x[0], y[0])
            for i in iterRange(1, count):
                path.lineTo(x[i], y[i])

        self.setPath(path)
Example #9
0
    def updatePosition(self, scene):
        path = QPainterPath()

        self.prepareGeometryChange()

        count = len(self._longitudes)
        if count > 0:
            x, y = scene.posFromLonLat(self._longitudes, self._latitudes)
            path.moveTo(x[0], y[0])
            for i in iterRange(1, count):
                path.lineTo(x[i], y[i])

        self.setPath(path)
Example #10
0
    def shape(self):
        if self._shape is None:
            radius = self.getState()['size'][1]
            p = QPainterPath()
            p.moveTo(Point(0, -radius))
            p.lineTo(Point(0, radius))
            p.moveTo(Point(-radius, 0))
            p.lineTo(Point(radius, 0))
            p = self.mapToDevice(p)
            stroker = QPainterPathStroker()
            stroker.setWidth(10)
            outline = stroker.createStroke(p)
            self._shape = self.mapFromDevice(outline)

        return self._shape
Example #11
0
    def shape(self):
        # (used for hitbox for menu)

        centerangle = self.innerhandle.pos().angle(Point(1, 0))
        startangle = centerangle - self.thetawidth / 2
        endangle = centerangle + self.thetawidth / 2
        r1v = self.innerhandle.pos().norm()

        # Draw out the path in external space
        path = QPainterPath()
        path.moveTo(-1.0 * self.widthhandle.pos() + 2 * self.widthhandle.pos().dot(r1v) * r1v)
        path.arcTo(QCircRectF(radius=self.innerradius), -startangle, -self.thetawidth)  # inside
        path.lineTo(self.widthhandle.pos())  # ? side
        path.arcTo(QCircRectF(radius=self.outerradius), -endangle, self.thetawidth)  # outside
        path.lineTo(-1.0 * self.widthhandle.pos() + 2 * self.widthhandle.pos().dot(r1v) * r1v)
        return path
Example #12
0
    def paintEvent(self, event) -> None:
        super(ToolTip, self).paintEvent(event)

        x = self.rect().x() + self._anchor_width
        y = self.rect().y() + self._anchor_width
        w = self.rect().width() - self._anchor_width * 2
        h = self.rect().height() - self._anchor_width * 2

        # 背景
        painter = QPainter(self)
        path = QPainterPath()
        path.addRoundedRect(QRectF(x, y, w, h), 4, 4)
        # 画锚
        if self._direction == ToolTip.TOP:
            x1 = x + w / 2 - self._anchor_width
            y1 = y + h
            x2 = x + w / 2 + self._anchor_width
            y2 = y + h
            x3 = x + w / 2
            y3 = y + h + self._anchor_width
            path.moveTo(x1, y1)
            path.lineTo(x2, y2)
            path.lineTo(x3, y3)
        elif self._direction == ToolTip.BOTTOM:
            x1 = x + w / 2 - self._anchor_width
            y1 = y
            x2 = x + w / 2 + self._anchor_width
            y2 = y
            x3 = x + w / 2
            y3 = y - self._anchor_width
            path.moveTo(x1, y1)
            path.lineTo(x2, y2)
            path.lineTo(x3, y3)
        elif self._direction == ToolTip.RIGHT:
            x1 = x
            y1 = y + h / 2 - self._anchor_width
            x2 = x
            y2 = y + h / 2 + self._anchor_width
            x3 = x - self._anchor_width
            y3 = y + h / 2
            path.moveTo(x1, y1)
            path.lineTo(x2, y2)
            path.lineTo(x3, y3)
        elif self._direction == ToolTip.LEFT:
            x1 = x + w
            y1 = y + h / 2 - self._anchor_width
            x2 = x + w
            y2 = y + h / 2 + self._anchor_width
            x3 = x + w + self._anchor_width
            y3 = y + h / 2
            path.moveTo(x1, y1)
            path.lineTo(x2, y2)
            path.lineTo(x3, y3)

        painter.fillPath(path, ResourceLoader().qt_color_separator_dark)
    def paint(self, painter, fill=False, canvas=None):
        from ..application import Application

        mainwindow = Application.get_main_window()
        line_pen, last_line_pen, fill_color = self._get_pens_and_colors(
            canvas, mainwindow.lineColor, mainwindow.fillColor)
        scale = self.get_scale(canvas)
        # Draw all vertices
        self.paint_vertices(painter, self.points, scale, self._highlightIndex,
                            self._highlightMode)
        line_path1, line_path2 = QPainterPath(), QPainterPath()
        fill_path = line_path1
        # Get path for committed and uncommitted parts
        # respectively and draw with different colors
        if self.shape_type == 'curve' and self.points:
            # Bezier curve needs to be fitted as a whole,
            # so reimplementing this part here.
            refined_points = BezierB(self.points).smooth()
            sep_idx = refined_points.index(self.points[-1])
            line_path1.moveTo(refined_points[0])
            for p in refined_points[:sep_idx]:
                line_path1.lineTo(p)
            line_path2.moveTo(refined_points[sep_idx])
            for p in refined_points[sep_idx:]:
                line_path2.lineTo(p)
        elif self.shape_type in ['circle', 'rectangle']:
            painter.setPen(line_pen)
            line_path2 = self.get_line_path(self.points, self.shape_type)
            painter.setPen(last_line_pen)
            painter.drawPath(line_path2)
            fill_path = line_path2
        elif len(self.points) >= 2:
            # Otherwise, just get 2 different line paths,
            # painting with different colors.
            # Use type == 'line' even with polygon to prevent connecting back.
            line_path1 = self.get_line_path(self.points[:-1], 'line')
            line_path2 = self.get_line_path(self.points[-2:], 'line')
        painter.setPen(line_pen)
        painter.drawPath(line_path1)
        painter.setPen(last_line_pen)
        painter.drawPath(line_path2)
        if fill:
            painter.fillPath(fill_path, fill_color)
Example #14
0
    def drawLine(self, qp, value: int):
        """Draw line on triangle indicating value.

        Parameters
        ----------
        qp: QPainter object
        value: int
            Value of highlight thickness.
        """
        col = QColor('white')
        qp.setPen(QPen(col, 2))
        qp.setBrush(col)
        path = QPainterPath()
        path.moveTo(value, 15)

        path.lineTo(value, 0)
        path.closeSubpath()

        qp.drawPath(path)
        self.valueChanged.emit(self._value)
Example #15
0
 def draw_target_path(self) -> None:
     """Draw solving path."""
     pen = QPen()
     pen.setWidth(self.path_width)
     for i, n in enumerate(sorted(self.target_path)):
         path = self.target_path[n]
         if self.monochrome:
             line, dot = target_path_style(0)
         else:
             line, dot = target_path_style(i + 1)
         pen.setColor(line)
         self.painter.setPen(pen)
         if len(path) == 1:
             x, y = path[0]
             p = QPointF(x, -y) * self.zoom
             self.painter.drawText(p + QPointF(6, -6), f"P{n}")
             pen.setColor(dot)
             self.painter.setPen(pen)
             self.draw_circle(p, self.joint_size)
         else:
             painter_path = QPainterPath()
             for j, (x, y) in enumerate(path):
                 p = QPointF(x, -y) * self.zoom
                 self.draw_circle(p, self.joint_size)
                 if j == 0:
                     self.painter.drawText(p + QPointF(6, -6), f"P{n}")
                     painter_path.moveTo(p)
                 else:
                     x2, y2 = path[j - 1]
                     self.__draw_arrow(x, -y, x2, -y2, zoom=True)
                     painter_path.lineTo(p)
             pen.setColor(line)
             self.painter.setPen(pen)
             self.painter.drawPath(painter_path)
             for x, y in path:
                 pen.setColor(dot)
                 self.painter.setPen(pen)
                 self.draw_circle(
                     QPointF(x, -y) * self.zoom, self.joint_size)
     self.painter.setBrush(Qt.NoBrush)
Example #16
0
 def get_line_path(points, shape_type):
     line_path = QPainterPath()
     if shape_type == 'rectangle' and len(points) == 2:
         rectangle = Shape.getRectFromLine(*points)
         line_path.addRect(rectangle)
     elif shape_type == 'circle' and len(points) == 2:
         rectangle = Shape.getCircleRectFromLine(points)
         line_path.addEllipse(rectangle)
     elif shape_type == 'linestrip' and points:
         line_path.moveTo(points[0])
         for p in points:
             line_path.lineTo(p)
     elif shape_type in ['curve', 'freeform'] and points:
         # Paint Bezier curve across given points.
         refined_points = BezierB(points).smooth()
         line_path.moveTo(refined_points[0])
         for p in refined_points:
             line_path.lineTo(p)
     elif points:
         line_path.moveTo(points[0])
         for p in points:
             line_path.lineTo(p)
         if shape_type == 'polygon':
             line_path.lineTo(points[0])
     return line_path
Example #17
0
 def drawPolygon(self, *args):
     if len(args) == 3:
         points, pointCount, mode = args
     elif len(args) == 2:
         points, mode = args
         pointCount = len(points)
     else:
         raise TypeError("Unexpected arguments")
     device = self.nullDevice()
     if device is None:
         return
     if device.mode() == QwtNullPaintDevice.PathMode:
         path = QPainterPath()
         if pointCount > 0:
             path.moveTo(points[0])
             for i in range(1, pointCount):
                 path.lineTo(points[i])
             if mode != QPaintEngine.PolylineMode:
                 path.closeSubpath()
         device.drawPath(path)
         return
     device.drawPolygon(points, pointCount, mode)
Example #18
0
 def draw_curve(self, path: Sequence[_Coord]) -> None:
     """Draw path as curve."""
     if len(set(path)) < 2:
         return
     painter_path = QPainterPath()
     error = False
     for i, (x, y) in enumerate(path):
         if isnan(x):
             error = True
             self.painter.drawPath(painter_path)
             painter_path = QPainterPath()
         else:
             p = QPointF(x, -y) * self.zoom
             if i == 0:
                 painter_path.moveTo(p)
                 self.draw_circle(p, 2)
                 continue
             if error:
                 painter_path.moveTo(p)
                 error = False
             else:
                 painter_path.lineTo(p)
     self.painter.drawPath(painter_path)
Example #19
0
    def _paintBackgroundCross(cls, painter):
        grey = QColor(220, 220, 220)
        greyAccent = QColor(180, 180, 180)

        painter.setBrush(QBrush(grey))
        painter.setPen(QPen(greyAccent, 1))

        path = QPainterPath()
        h0 = -86
        h1 = -18
        h2 = 18
        h3 = 86
        v0 = -86
        v1 = -18
        v2 = 18
        v3 = 86
        c = 7

        path.moveTo(v0, h1)
        path.lineTo(v1 - c, h1)
        path.lineTo(v1, h1 - c)
        path.lineTo(v1, h0)
        path.lineTo(v2, h0)
        path.lineTo(v2, h1 - c)
        path.lineTo(v2 + c, h1)
        path.lineTo(v3, h1)
        path.lineTo(v3, h2)
        path.lineTo(v2 + c, h2)
        path.lineTo(v2, h2 + c)
        path.lineTo(v2, h3)
        path.lineTo(v1, h3)
        path.lineTo(v1, h2 + c)
        path.lineTo(v1 - c, h2)
        path.lineTo(v0, h2)
        path.closeSubpath()
        painter.drawPath(path)
Example #20
0
    def drawTriangle(self, qp):
        """Draw triangle.

        Parameters
        ----------
        qp: QPainter object
        """
        width = self.rect().width()
        height = self.rect().height()

        col = QColor(135, 206, 235)
        qp.setPen(QPen(col, 1))
        qp.setBrush(col)
        path = QPainterPath()

        height = 10
        path.moveTo(0, height)

        path.lineTo(width, height)

        path.lineTo(width, 0)
        path.closeSubpath()

        qp.drawPath(path)
Example #21
0
from qtpy.QtGui import QApplication, QPen, QPainterPath, QTransform
from qtpy.QtCore import Qt, QPointF
from qwt import QwtPlot, QwtPlotCurve, QwtSymbol
import numpy as np
import os.path as osp

app = QApplication([])

# --- Construct custom symbol ---

path = QPainterPath()
path.moveTo(0, 8)
path.lineTo(0, 5)
path.lineTo(-3, 5)
path.lineTo(0, 0)
path.lineTo(3, 5)
path.lineTo(0, 5)

transform = QTransform()
transform.rotate(-30.0)
path = transform.map(path)

pen = QPen(Qt.black, 2)
pen.setJoinStyle(Qt.MiterJoin)

symbol = QwtSymbol()
symbol.setPen(pen)
symbol.setBrush(Qt.red)
symbol.setPath(path)
symbol.setPinPoint(QPointF(0.0, 0.0))
symbol.setSize(10, 14)
Example #22
0
    def paintEvent(self, event):

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)

        painter.setPen(Qt.NoPen)
        if self.hover:
            painter.setBrush(
                QColor(self.back_color.red() + 30,
                       self.back_color.green() + 30,
                       self.back_color.blue() + 30))
            self.lineEdit.set_back_color(
                QColor(self.back_color.red() + 30,
                       self.back_color.green() + 30,
                       self.back_color.blue() + 30))
        else:
            painter.setBrush(self.back_color)
            self.lineEdit.set_back_color(self.back_color)

        painter.drawRoundedRect(QRect(0, 0, self.width(), self.height()),
                                self.border_radius, self.border_radius)

        pen = QPen(self.down_arrow_color, self.drop_thick, Qt.SolidLine)
        painter.setPen(pen)
        self.down_arrow_poly = QPolygon()
        x1 = QPoint(self.label_width + float(self.height() / 3),
                    float(self.height() * 0.6))
        x2 = QPoint(
            self.label_width + float(self.height() / 3) +
            float(self.height() * self.rate / 2), float(self.height() * 0.75))
        x3 = QPoint(self.width() - float(self.height() / 3),
                    float(self.height() * 0.6))
        self.down_arrow_poly << x1 << x2 << x3

        check_path = QPainterPath()
        check_path.moveTo(x1)
        check_path.lineTo(x2)
        check_path.lineTo(x3)
        check_path.lineTo(x1)
        painter.drawPath(check_path)
        if self.down_arrow_color == self.arrow_activate_color:
            painter.fillPath(check_path, QBrush(self.down_arrow_color))
        else:
            if self.hover:
                painter.fillPath(
                    check_path,
                    QColor(self.back_color.red() + 30,
                           self.back_color.green() + 30,
                           self.back_color.blue() + 30))
            else:
                painter.fillPath(check_path, QBrush(self.back_color))

        pen = QPen(self.up_arrow_color, self.drop_thick, Qt.SolidLine)
        painter.setPen(pen)

        x1 = QPoint(self.label_width + float(self.height() / 3),
                    float(self.height() * 0.4))
        x2 = QPoint(
            self.label_width + float(self.height() / 3) +
            float(self.height() * self.rate / 2), float(self.height() * 0.25))
        x3 = QPoint(self.width() - float(self.height() / 3),
                    float(self.height() * 0.4))
        self.up_arrow_poly = QPolygon()
        self.up_arrow_poly << x1 << x2 << x3

        check_path = QPainterPath()
        check_path.moveTo(x1)
        check_path.lineTo(x2)
        check_path.lineTo(x3)
        check_path.lineTo(x1)
        painter.drawPath(check_path)
        if self.up_arrow_color == self.arrow_activate_color:
            painter.fillPath(check_path, QBrush(self.up_arrow_color))
        else:
            if self.hover:
                painter.fillPath(
                    check_path,
                    QColor(self.back_color.red() + 30,
                           self.back_color.green() + 30,
                           self.back_color.blue() + 30))
            else:
                painter.fillPath(check_path, QBrush(self.back_color))
    def drawPath(self):
        p = QPainterPath()

        x, y = self.opts['x'], self.opts['y']
        if x is None or y is None:
            self.path = p
            return

        if self.opts['xlog']:
            x = np.log10(x)
        if self.opts['ylog']:
            y = np.log10(y)

        beam = self.opts['beam']

        height, top, bottom = self.opts['height'], self.opts['top'], self.opts[
            'bottom']
        if height is not None or top is not None or bottom is not None:
            ## draw vertical error bars
            if height is not None:
                y1 = y - height / 2.
                y2 = y + height / 2.
            else:
                if bottom is None:
                    y1 = y
                else:
                    y1 = y - bottom
                if top is None:
                    y2 = y
                else:
                    y2 = y + top

            for i in range(len(x)):
                p.moveTo(x[i], y1[i])
                p.lineTo(x[i], y2[i])

            if beam is not None and beam > 0:
                x1 = x - beam / 2.
                x2 = x + beam / 2.
                if height is not None or top is not None:
                    for i in range(len(x)):
                        p.moveTo(x1[i], y2[i])
                        p.lineTo(x2[i], y2[i])
                if height is not None or bottom is not None:
                    for i in range(len(x)):
                        p.moveTo(x1[i], y1[i])
                        p.lineTo(x2[i], y1[i])

        width, right, left = self.opts['width'], self.opts['right'], self.opts[
            'left']
        if width is not None or right is not None or left is not None:
            ## draw vertical error bars
            if width is not None:
                x1 = x - width / 2.
                x2 = x + width / 2.
            else:
                if left is None:
                    x1 = x
                else:
                    x1 = x - left
                if right is None:
                    x2 = x
                else:
                    x2 = x + right

            for i in range(len(x)):
                p.moveTo(x1[i], y[i])
                p.lineTo(x2[i], y[i])

            if beam is not None and beam > 0:
                y1 = y - beam / 2.
                y2 = y + beam / 2.
                if width is not None or right is not None:
                    for i in range(len(x)):
                        p.moveTo(x2[i], y1[i])
                        p.lineTo(x2[i], y2[i])
                if width is not None or left is not None:
                    for i in range(len(x)):
                        p.moveTo(x1[i], y1[i])
                        p.lineTo(x1[i], y2[i])

        self.path = p
        self.prepareGeometryChange()
Example #24
0
class FadingTipBox(FadingDialog):
    """ """
    def __init__(self, parent, opacity, duration, easing_curve, tour=None):
        super(FadingTipBox, self).__init__(parent, opacity, duration,
                                           easing_curve)
        self.holder = self.anim  # needed for qt to work
        self.parent = parent
        self.tour = tour

        self.frames = None
        self.color_top = QColor.fromRgb(230, 230, 230)
        self.color_back = QColor.fromRgb(255, 255, 255)
        self.offset_shadow = 0
        self.fixed_width = 300

        self.key_pressed = None

        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint |
                            Qt.WindowStaysOnTopHint)
        self.setModal(False)

        # Widgets
        def toolbutton(icon):
            bt = QToolButton()
            bt.setAutoRaise(True)
            bt.setIcon(icon)
            return bt

        self.button_close = toolbutton(ima.icon("tour.close"))
        self.button_home = toolbutton(ima.icon("tour.home"))
        self.button_previous = toolbutton(ima.icon("tour.previous"))
        self.button_end = toolbutton(ima.icon("tour.end"))
        self.button_next = toolbutton(ima.icon("tour.next"))
        self.button_run = QPushButton(_('Run code'))
        self.button_disable = None
        self.button_current = QToolButton()
        self.label_image = QLabel()

        self.label_title = QLabel()
        self.combo_title = QComboBox()
        self.label_current = QLabel()
        self.label_content = QLabel()

        self.label_content.setMinimumWidth(self.fixed_width)
        self.label_content.setMaximumWidth(self.fixed_width)

        self.label_current.setAlignment(Qt.AlignCenter)

        self.label_content.setWordWrap(True)

        self.widgets = [self.label_content, self.label_title,
                        self.label_current, self.combo_title,
                        self.button_close, self.button_run, self.button_next,
                        self.button_previous, self.button_end,
                        self.button_home, self.button_current]

        arrow = get_image_path('hide.png')

        self.stylesheet = '''QComboBox {
                             padding-left: 5px;
                             background-color: rgbs(230,230,230,100%);
                             border-width: 0px;
                             border-radius: 0px;
                             min-height:20px;
                             max-height:20px;
                             }

                             QComboBox::drop-down  {
                             subcontrol-origin: padding;
                             subcontrol-position: top left;
                             border-width: 0px;
                             }
                             
                             QComboBox::down-arrow {
                             image: url(''' + arrow + ''');
                             }
                             
                             '''
        # Windows fix, slashes should be always in unix-style
        self.stylesheet = self.stylesheet.replace('\\', '/')

        self.setFocusPolicy(Qt.StrongFocus)
        for widget in self.widgets:
            widget.setFocusPolicy(Qt.NoFocus)
            widget.setStyleSheet(self.stylesheet)

        layout_top = QHBoxLayout()
        layout_top.addWidget(self.combo_title)
        layout_top.addStretch()
        layout_top.addWidget(self.button_close)
        layout_top.addSpacerItem(QSpacerItem(self.offset_shadow,
                                             self.offset_shadow))

        layout_content = QHBoxLayout()
        layout_content.addWidget(self.label_content)
        layout_content.addWidget(self.label_image)
        layout_content.addSpacerItem(QSpacerItem(5, 5))

        layout_run = QHBoxLayout()
        layout_run.addStretch()
        layout_run.addWidget(self.button_run)
        layout_run.addStretch()
        layout_run.addSpacerItem(QSpacerItem(self.offset_shadow,
                                             self.offset_shadow))

        layout_navigation = QHBoxLayout()
        layout_navigation.addWidget(self.button_home)
        layout_navigation.addWidget(self.button_previous)
        layout_navigation.addStretch()
        layout_navigation.addWidget(self.label_current)
        layout_navigation.addStretch()
        layout_navigation.addWidget(self.button_next)
        layout_navigation.addWidget(self.button_end)
        layout_navigation.addSpacerItem(QSpacerItem(self.offset_shadow,
                                                    self.offset_shadow))

        layout = QVBoxLayout()
        layout.addLayout(layout_top)
        layout.addStretch()
        layout.addSpacerItem(QSpacerItem(15, 15))
        layout.addLayout(layout_content)
        layout.addLayout(layout_run)
        layout.addStretch()
        layout.addSpacerItem(QSpacerItem(15, 15))
        layout.addLayout(layout_navigation)
        layout.addSpacerItem(QSpacerItem(self.offset_shadow,
                                         self.offset_shadow))

        layout.setSizeConstraint(QLayout.SetFixedSize)

        self.setLayout(layout)

        self.set_funcs_before_fade_in([self._disable_widgets])
        self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus])
        self.set_funcs_before_fade_out([self._disable_widgets])

        self.setContextMenuPolicy(Qt.CustomContextMenu)

        # signals and slots
        # These are defined every time by the AnimatedTour Class

    def _disable_widgets(self):
        """ """
        for widget in self.widgets:
            widget.setDisabled(True)

    def _enable_widgets(self):
        """ """
        self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint |
                            Qt.WindowStaysOnTopHint)
        for widget in self.widgets:
            widget.setDisabled(False)

        if self.button_disable == 'previous':
            self.button_previous.setDisabled(True)
            self.button_home.setDisabled(True)
        elif self.button_disable == 'next':
            self.button_next.setDisabled(True)
            self.button_end.setDisabled(True)

    def set_data(self, title, content, current, image, run, frames=None,
                 step=None):
        """ """
        self.label_title.setText(title)
        self.combo_title.clear()
        self.combo_title.addItems(frames)
        self.combo_title.setCurrentIndex(step)
#        min_content_len = max([len(f) for f in frames])
#        self.combo_title.setMinimumContentsLength(min_content_len)

        # Fix and try to see how it looks with a combo box
        self.label_current.setText(current)
        self.button_current.setText(current)
        self.label_content.setText(content)
        self.image = image

        if image is None:
            self.label_image.setFixedHeight(1)
            self.label_image.setFixedWidth(1)
        else:
            extension = image.split('.')[-1]
            self.image = QPixmap(get_image_path(image), extension)
            self.label_image.setPixmap(self.image)
            self.label_image.setFixedSize(self.image.size())

        if run is None:
            self.button_run.setVisible(False)
        else:
            self.button_run.setDisabled(False)
            self.button_run.setVisible(True)

        # Refresh layout
        self.layout().activate()

    def set_pos(self, x, y):
        """ """
        self.x = x
        self.y = y
        self.move(QPoint(x, y))

    def build_paths(self):
        """ """
        geo = self.geometry()
        radius = 0
        shadow = self.offset_shadow
        x0, y0 = geo.x(), geo.y()
        width, height = geo.width() - shadow, geo.height() - shadow

        left, top = 0, 0
        right, bottom = width, height

        self.round_rect_path = QPainterPath()
        self.round_rect_path.moveTo(right, top + radius)
        self.round_rect_path.arcTo(right-radius, top, radius, radius, 0.0,
                                   90.0)
        self.round_rect_path.lineTo(left+radius, top)
        self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0)
        self.round_rect_path.lineTo(left, bottom-radius)
        self.round_rect_path.arcTo(left, bottom-radius, radius, radius, 180.0,
                                   90.0)
        self.round_rect_path.lineTo(right-radius, bottom)
        self.round_rect_path.arcTo(right-radius, bottom-radius, radius, radius,
                                   270.0, 90.0)
        self.round_rect_path.closeSubpath()

        # Top path
        header = 36
        offset = 2
        left, top = offset, offset
        right = width - (offset)
        self.top_rect_path = QPainterPath()
        self.top_rect_path.lineTo(right, top + radius)
        self.top_rect_path.moveTo(right, top + radius)
        self.top_rect_path.arcTo(right-radius, top, radius, radius, 0.0, 90.0)
        self.top_rect_path.lineTo(left+radius, top)
        self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0)
        self.top_rect_path.lineTo(left, top + header)
        self.top_rect_path.lineTo(right, top + header)

    def paintEvent(self, event):
        """ """
        self.build_paths()

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillPath(self.round_rect_path, self.color_back)
        painter.fillPath(self.top_rect_path, self.color_top)
        painter.strokePath(self.round_rect_path, QPen(Qt.gray, 1))

        # TODO: Build the pointing arrow?

    def keyReleaseEvent(self, event):
        """ """
        key = event.key()
        self.key_pressed = key

        keys = [Qt.Key_Right, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up,
                Qt.Key_Escape, Qt.Key_PageUp, Qt.Key_PageDown,
                Qt.Key_Home, Qt.Key_End, Qt.Key_Menu]

        if key in keys:
            if not self.is_fade_running():
                self.sig_key_pressed.emit()

    def mousePressEvent(self, event):
        """override Qt method"""
        # Raise the main application window on click
        self.parent.raise_()
        self.raise_()

        if event.button() == Qt.RightButton:
            pass
#            clicked_widget = self.childAt(event.x(), event.y())
#            if clicked_widget == self.label_current:
#            self.context_menu_requested(event)

    def focusOutEvent(self, event):
        """Override Qt method."""
        # To be used so tips do not appear outside spyder
        self.tour.lost_focus()

    def context_menu_requested(self, event):
        """ """
        pos = QPoint(event.x(), event.y())
        menu = QMenu(self)

        actions = []
        action_title = create_action(self, _('Go to step: '), icon=QIcon())
        action_title.setDisabled(True)
        actions.append(action_title)
#        actions.append(create_action(self, _(': '), icon=QIcon()))

        add_actions(menu, actions)

        menu.popup(self.mapToGlobal(pos))

    def reject(self):
        """Qt method to handle escape key event"""
        if not self.is_fade_running():
            key = Qt.Key_Escape
            self.key_pressed = key
            self.sig_key_pressed.emit()
Example #25
0
class LineChartItem(ChartItem):
    """ Visualises the given data as line chart_tests.

    :param parent: Items parent
    """
    def __init__(self, parent=None):
        super(LineChartItem, self).__init__(parent)
        self._xData = None
        self._yData = None
        self._label = None
        # self._color = None
        self._bRect = None
        self.markers = {}

        self._showticks = False
        self._visible_range = None

        self._ordinate = None
        self._abscissa = None

    #     self._column = None
    #
    # @property
    # def column(self):
    #     return self._column

    @property
    def ordinate(self):
        """ Property to set/get the items ordinate name. """
        return self._ordinate

    @ordinate.setter
    def ordinate(self, value):
        self._ordinate = value

    @property
    def abscissa(self):
        """ Property to set/get the items abscissa name. """
        return self._abscissa

    @abscissa.setter
    def abscissa(self, value):
        self._abscissa = value

    @property
    def showTicks(self):
        """ Property if true the chart_tests will display tickmarks if the number of displayed data points is below
        400.
        """
        return self._showticks

    @showTicks.setter
    def showTicks(self, value):
        self._showticks = value
        self.visibleRangeChanged(self._visible_range)

    # @property
    # def color(self):
    #     return self._color

    @property
    def label(self):
        """ Property to get the items label. """
        return self._label

    def plot(self, data, index=None, label=None, color=QColor(Qt.red)):
        """ Sets the charts data points.

        :param data: ordinate values
        :param index: abscissa values. Optional, if not set datapoints are indexed starting with 0
        :param label: Label of the chart_tests.
        :param color: Color of the chart_tests
        """
        self._yData = data

        if index is not None:
            self._xData = index
        else:
            self._xData = np.arange(len(data))

        if label is not None:
            self._label = label

        self._color = color

        self._bRect = QRectF(
            QPointF(np.min(self._xData), np.min(self._yData)),
            QPointF(np.max(self._xData), np.max(self._yData)),
        )
        # _log.debug("Plot BB: {}".format(self._bRect))
        #
        # # TODO: Public access
        # self.canvas._items.append(self._bRect)

        self._makePath()

    def _makePath(self):
        self._path = QPainterPath()
        self._path.moveTo(self._xData[0], self._yData[0])

        for k, idx in enumerate(self._xData):
            d = self._yData[k]
            self._path.lineTo(idx, d)

    def boundingRect(self):
        """ Returns the bounding rect of the chart_tests item
        :return: Bounding Rectangle
        :rtype: QRectF
        """
        return self._bRect

    def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None):
        # _log.debug("LCI: paint")
        pen = makePen(self.color)
        p.setPen(pen)

        if self._path:
            p.drawPath(self._path)

        # if any(self.markers):
        #     # pen = makePen(Qt.yellow)
        #     # p.setPen(pen)
        #     # p.drawRects(self.markers)
        #
        #     for m in self.markers:
        #         marker = RectMarker(m)
        #         marker.setParentItem(self)

        if CONFIG.debug_layout:
            p.setPen(makePen(Qt.yellow))
            p.setBrush(Qt.transparent)
            p.drawRect(self._bRect)

    def visibleRangeChanged(self, rect=QRectF()):
        """ Slot that is called whenver the views visible range changed.

        :param rect: view rectangle.
        """

        _log.debug("Visible range changed to: {}".format(rect))
        self._visible_range = rect

        visible_indices = np.where(
            np.logical_and(
                np.logical_and(self._xData >= rect.left(),
                               self._xData <= rect.right()),
                np.logical_and(self._yData >= rect.top(),
                               self._yData <= rect.bottom()),
            ))[0]

        # _log.debug("Visible plot points idx: {}".format(visible_indices))

        # self.markers = []
        if len(visible_indices) < 400 and self.showTicks:
            # _log.debug("Too many indices for display")
            # return

            # self.markers = [QPointF(self._xData[idx], self._yData[idx]) for idx in visible_indices]
            _log.debug("Making markers")
            for idx in visible_indices:
                if idx not in self.markers:
                    pos = QPointF(self._xData[idx], self._yData[idx])
                    marker = RectMarker(pos)
                    self.markers[idx] = marker
                    marker.setParentItem(self)

        else:
            _log.debug("removing all markers")
            for k in self.markers:
                item = self.markers[k]
                self.scene().removeItem(item)
                # del self.markers[k]
            self.markers = {}

    def __del__(self):
        _log.debug("Finalize Linechart {}".format(self))
Example #26
0
    def _paintAbsDropIcon(self, painter, placement):
        self._configureBrushAndPen(painter, Qt.white, Qt.white)
        r = QRectF(-14, -14, 28, 28)
        painter.drawRoundedRect(r, 2, 2)

        self._configureBrushAndPen(painter, self.Blue, self.BlueAccent)

        title = {
            Placement.LEFT: QRectF(-10, -10, 10, 4),
            Placement.RIGHT: QRectF(0, -10, 10, 4),
            Placement.TOP: QRectF(-10, -10, 20, 4),
            Placement.BOTTOM: QRectF(-10, -2, 20, 4),
            Placement.TAB: None,
        }
        if title[placement] is not None:
            painter.drawRect(title[placement])

        if placement == self._activeAbsoluteRegion:
            self._configureBrushAndPen(painter, self.Yellow, self.BlueAccent)
        else:
            self._configureBrushAndPen(painter, self.BlueDim,
                                       self.BlueAccentDim)

        bg = {
            Placement.LEFT: QRectF(-10, -5, 10, 14),
            Placement.RIGHT: QRectF(0, -5, 10, 14),
            Placement.TOP: QRectF(-10, -5, 20, 7),
            Placement.BOTTOM: QRectF(-10, 2, 20, 7),
            Placement.TAB: None,
        }
        if bg[placement] is not None:
            painter.drawRect(bg[placement])

        if placement == Placement.LEFT:
            painter.setBrush(QBrush(self.Blue))
            painter.setPen(QPen(self.BlueAccent, 1))

            path = QPainterPath()
            path.moveTo(6, 0)
            path.lineTo(10, -4)
            path.lineTo(10, 4)
            path.closeSubpath()
            painter.drawPath(path)

        elif placement == Placement.TOP:
            painter.setBrush(QBrush(self.Blue))
            painter.setPen(QPen(self.BlueAccent, 1))

            path = QPainterPath()
            path.moveTo(0, 6)
            path.lineTo(-4, 10)
            path.lineTo(4, 10)
            path.closeSubpath()
            painter.drawPath(path)

        elif placement == Placement.RIGHT:
            painter.setBrush(QBrush(self.Blue))
            painter.setPen(QPen(self.BlueAccent, 1))

            path = QPainterPath()
            path.moveTo(-6, 0)
            path.lineTo(-10, -4)
            path.lineTo(-10, 4)
            path.closeSubpath()
            painter.drawPath(path)

        elif placement == Placement.BOTTOM:
            painter.setBrush(QBrush(self.Blue))
            painter.setPen(QPen(self.BlueAccent, 1))

            path = QPainterPath()
            path.moveTo(0, -6)
            path.lineTo(-4, -10)
            path.lineTo(4, -10)
            path.closeSubpath()
            painter.drawPath(path)
Example #27
0
 def drawFrame(
     self,
     painter,
     rect,
     palette,
     foregroundRole,
     frameWidth,
     midLineWidth,
     frameStyle,
 ):
     """
     Draw a rectangular frame
     
     :param QPainter painter: Painter
     :param QRectF rect: Frame rectangle
     :param QPalette palette: Palette
     :param QPalette.ColorRole foregroundRole: Palette
     :param int frameWidth: Frame width
     :param int midLineWidth: Used for `QFrame.Box`
     :param int frameStyle: bitwise OR´ed value of `QFrame.Shape` and `QFrame.Shadow`
     """
     if frameWidth <= 0 or rect.isEmpty():
         return
     shadow = frameStyle & QFrame.Shadow_Mask
     painter.save()
     if shadow == QFrame.Plain:
         outerRect = rect.adjusted(0.0, 0.0, -1.0, -1.0)
         innerRect = outerRect.adjusted(frameWidth, frameWidth, -frameWidth,
                                        -frameWidth)
         path = QPainterPath()
         path.addRect(outerRect)
         path.addRect(innerRect)
         painter.setPen(Qt.NoPen)
         painter.setBrush(palette.color(foregroundRole))
         painter.drawPath(path)
     else:
         shape = frameStyle & QFrame.Shape_Mask
         if shape == QFrame.Box:
             outerRect = rect.adjusted(0.0, 0.0, -1.0, -1.0)
             midRect1 = outerRect.adjusted(frameWidth, frameWidth,
                                           -frameWidth, -frameWidth)
             midRect2 = midRect1.adjusted(midLineWidth, midLineWidth,
                                          -midLineWidth, -midLineWidth)
             innerRect = midRect2.adjusted(frameWidth, frameWidth,
                                           -frameWidth, -frameWidth)
             path1 = QPainterPath()
             path1.moveTo(outerRect.bottomLeft())
             path1.lineTo(outerRect.topLeft())
             path1.lineTo(outerRect.topRight())
             path1.lineTo(midRect1.topRight())
             path1.lineTo(midRect1.topLeft())
             path1.lineTo(midRect1.bottomLeft())
             path2 = QPainterPath()
             path2.moveTo(outerRect.bottomLeft())
             path2.lineTo(outerRect.bottomRight())
             path2.lineTo(outerRect.topRight())
             path2.lineTo(midRect1.topRight())
             path2.lineTo(midRect1.bottomRight())
             path2.lineTo(midRect1.bottomLeft())
             path3 = QPainterPath()
             path3.moveTo(midRect2.bottomLeft())
             path3.lineTo(midRect2.topLeft())
             path3.lineTo(midRect2.topRight())
             path3.lineTo(innerRect.topRight())
             path3.lineTo(innerRect.topLeft())
             path3.lineTo(innerRect.bottomLeft())
             path4 = QPainterPath()
             path4.moveTo(midRect2.bottomLeft())
             path4.lineTo(midRect2.bottomRight())
             path4.lineTo(midRect2.topRight())
             path4.lineTo(innerRect.topRight())
             path4.lineTo(innerRect.bottomRight())
             path4.lineTo(innerRect.bottomLeft())
             path5 = QPainterPath()
             path5.addRect(midRect1)
             path5.addRect(midRect2)
             painter.setPen(Qt.NoPen)
             brush1 = palette.dark().color()
             brush2 = palette.light().color()
             if shadow == QFrame.Raised:
                 brush1, brush2 = brush2, brush1
             painter.setBrush(brush1)
             painter.drawPath(path1)
             painter.drawPath(path4)
             painter.setBrush(brush2)
             painter.drawPath(path2)
             painter.drawPath(path3)
             painter.setBrush(palette.mid())
             painter.drawPath(path5)
         else:
             outerRect = rect.adjusted(0.0, 0.0, -1.0, -1.0)
             innerRect = outerRect.adjusted(
                 frameWidth - 1.0,
                 frameWidth - 1.0,
                 -(frameWidth - 1.0),
                 -(frameWidth - 1.0),
             )
             path1 = QPainterPath()
             path1.moveTo(outerRect.bottomLeft())
             path1.lineTo(outerRect.topLeft())
             path1.lineTo(outerRect.topRight())
             path1.lineTo(innerRect.topRight())
             path1.lineTo(innerRect.topLeft())
             path1.lineTo(innerRect.bottomLeft())
             path2 = QPainterPath()
             path2.moveTo(outerRect.bottomLeft())
             path2.lineTo(outerRect.bottomRight())
             path2.lineTo(outerRect.topRight())
             path2.lineTo(innerRect.topRight())
             path2.lineTo(innerRect.bottomRight())
             path2.lineTo(innerRect.bottomLeft())
             painter.setPen(Qt.NoPen)
             brush1 = palette.dark().color()
             brush2 = palette.light().color()
             if shadow == QFrame.Raised:
                 brush1, brush2 = brush2, brush1
             painter.setBrush(brush1)
             painter.drawPath(path1)
             painter.setBrush(brush2)
             painter.drawPath(path2)
     painter.restore()
Example #28
0
class Connection_Item(QGraphicsPathItem):
    def __init__(self, connection, parent):
        super().__init__()
        self._connection = connection
        self._source_ui = self._find_ui(parent, connection.source.connector)
        self._sink_ui = self._find_ui(parent, connection.sink.connector)
        self.avoid_conn = None
        self._duplicate_is = None
        self._duplicate_of = None
        self._switch_direction_count = 1
        self.path = QPainterPath()
        self.stroker_path = QPainterPath()
        self.stroker = QPainterPathStroker()
        self.stroker.setWidth(8)
        self.update_endpoints()
        self.setZValue(-10)
        self.arrow = QGraphicsPolygonItem()
        self._set_default_appearance()
        self.setFlag(self.ItemIsFocusable)
        self._ports_item = Connection_Ports_Item()
        self._ports_item.setParentItem(self)
        self._timer = QTimer(self.scene())
        self._timer.setSingleShot(True)
        self._timer.setSingleShot(True)
        self._timer.timeout.connect(self._start_hover)
        self._hover_pos = 0, 0
        self.set_show_connection_ports_on_hover(False)

    def shape(self):
        return self.stroker_path

    def setPath(self, path):
        super().setPath(path)
        self.stroker_path = self.stroker.createStroke(path)

    def _set_default_appearance(self):
        self.setPen(QPen(Qt.black, 2))
        self.arrow.setPen(QPen(Qt.black))
        self.arrow.setBrush(QBrush(Qt.black))
        self._arrow_height = 8
        self.update_from_avoid_router()  # trigger arrow size change

    def focusInEvent(self, event):
        self.setPen(QPen(highlight_color, 4))
        self.arrow.setPen(QPen(highlight_color))
        self.arrow.setBrush(QBrush(highlight_color))
        self._arrow_height = 12
        self.update_from_avoid_router()  # trigger arrow size change
        super().focusInEvent(event)

    def focusOutEvent(self, event):
        self._set_default_appearance()
        super().focusOutEvent(event)

    def keyPressEvent(self, event):
        key = event.key()
        if (key == Qt.Key_Delete):
            self.parentItem().remove_connection(self)
            return
        elif (key == Qt.Key_D):
            self._switch_direction()
            return
        super().keyPressEvent(event)

    def _switch_direction(self):
        if self._duplicate_is:
            self.parentItem().remove_connection(self._duplicate_is)
            self._switch_direction_count = 0
        elif self._switch_direction_count < 2:
            sink = self._connection.sink
            self._connection.sink = self._connection.source
            self._connection.source = sink
            self._source_ui = self._find_ui(self.parentItem(),
                                            self._connection.source.connector)
            self._sink_ui = self._find_ui(self.parentItem(),
                                          self._connection.sink.connector)
            self._switch_direction_count += 1
        else:
            conn = diagram.Connection(
                source=self._connection.sink,
                sink=self._connection.source,
            )
            self.parentItem().add_connection(conn)
            self._switch_direction_count = 3
        self.update_endpoints()
        self.parentItem()._hide_duplicate_connections()
        if self._switch_direction_count == 0:
            self._switch_direction()

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            self._switch_direction()
            return  # Do not call mousePressEvent, will pass on to diagram
        super().mouseDoubleClickEvent(event)

    def set_show_connection_ports_on_hover(self, show):
        if not show:
            self._ports_item.hide()
        self.setAcceptHoverEvents(show)

    def hoverEnterEvent(self, event):
        w = self._ports_item.rect().width()
        h = self._ports_item.rect().height()
        x = event.pos().x() - w / 2.0
        y = event.pos().y() - h / 2.0
        self._hover_pos = x, y
        self._timer.start(200)

    def hoverLeaveEvent(self, event):
        self._stop_hover()

    def _start_hover(self):
        if self.hasFocus():
            return
        #print("start hover", [a.name for a in self._connection.source_ports])
        x, y = self._hover_pos
        self._ports_item.setX(x)
        self._ports_item.setY(y)
        self.setZValue(10)
        self._ports_item.show()

    def _stop_hover(self):
        self._timer.stop()
        self._ports_item.hide()
        self.setZValue(-10)

    def _find_ui(self, parent, c):
        result = None
        for b_ui in parent._block_items:
            for c_ui in b_ui._connectors:
                if c_ui._connector == c:
                    return c_ui
        return result

    def _get_endpoint(self, c_ui):
        x, y = c_ui.get_connection_point()
        if x is None:
            return None, None
        p = self.mapToParent(
            self.mapFromScene(c_ui.parentItem().mapToScene(x, y)))
        return p.x(), p.y()

    def update_endpoints(self):
        self.x1, self.y1 = self._get_endpoint(self._source_ui)
        self.x2, self.y2 = self._get_endpoint(self._sink_ui)
        if self.x1 is None or self.x2 is None:
            return False
        self.path = QPainterPath()
        self.path.moveTo(self.x1, self.y1)
        self.path.lineTo(self.x2, self.y2)
        self.setPath(self.path)
        self._update_avoid()
        return True

    def _update_avoid(self):
        if self.parentItem():
            avoid_router = self.parentItem().avoid_router
            src = avoid.ConnEnd(avoid.Point(self.x1, self.y1))
            if self.isVisible():
                dest = avoid.ConnEnd(avoid.Point(self.x2, self.y2))
            else:
                dest = src  # Don't route duplicate connection
            if self.avoid_conn is None:
                self.avoid_conn = avoid.ConnRef(avoid_router, src, dest)
            else:
                self.avoid_conn.setEndpoints(src, dest)

    def update_from_avoid_router(self):
        if self.avoid_conn is not None and self.avoid_conn.needsRepaint():
            radius = self.parentItem().route_radius
            route = self.avoid_conn.displayRoute()
            self.path = QPainterPath()
            last_i = route.size() - 1
            for i in range(0, route.size()):
                point = route.at(i)
                if i > 0:
                    last_point = route.at(i - 1)
                    last_path_point = self.path.currentPosition()
                    if point.y == last_point.y:  # horizontal line
                        if point.x > last_point.x:  # right
                            sign = 1
                        else:  # left
                            sign = -1
                        self.path.quadTo(last_point.x, last_point.y,
                                         last_point.x + sign * radius, point.y)
                        if i == last_i:
                            my_x = point.x
                        else:
                            my_x = point.x - sign * radius
                        self.path.lineTo(my_x, point.y)
                    elif point.x == last_point.x:  # vertical line
                        if point.y > last_point.y:  # down
                            sign = 1
                        else:  # up
                            sign = -1
                        self.path.quadTo(last_point.x, last_point.y, point.x,
                                         last_point.y + sign * radius)
                        if i == last_i:
                            my_y = point.y
                        else:
                            my_y = point.y - sign * radius
                        self.path.lineTo(point.x, my_y)
                    else:
                        self.path.lineTo(point.x, point.y)
                else:
                    self.path.moveTo(point.x, point.y)
            self.setPath(self.path)

            sink = self._sink_ui
            entry_from = "L"
            x = 0
            if route.at(route.size() - 1).x < route.at(route.size() - 2).x:
                entry_from = "R"
                x = sink.parentItem().rect().width()
            if self._duplicate_of:
                route = self._duplicate_of.avoid_conn.displayRoute()
                if route.at(0).x < route.at(1).x:
                    entry_from = "R"
                    x = sink.parentItem().rect().width()
            y = sink.y() + sink.rect().height() / 2.0
            p = self.mapToParent(
                self.mapFromScene(sink.parentItem().mapToScene(x, y)))
            xc, yc = p.x(), p.y()
            arrow_h = self._arrow_height
            arrow_y = arrow_h / 2.0
            arrow_x = sqrt(arrow_h * arrow_h - arrow_y * arrow_y)
            poly = QPolygonF()
            if entry_from == "L":
                poly << QPointF(xc - arrow_x, yc)
                poly << QPointF(xc - arrow_x, yc + arrow_y)
                poly << QPointF(xc, yc)
                poly << QPointF(xc - arrow_x, yc - arrow_y)
                poly << QPointF(xc - arrow_x, yc)
            else:
                poly << QPointF(xc + arrow_x, yc)
                poly << QPointF(xc + arrow_x, yc + arrow_y)
                poly << QPointF(xc, yc)
                poly << QPointF(xc + arrow_x, yc - arrow_y)
                poly << QPointF(xc + arrow_x, yc)
            self.arrow.setPolygon(poly)

    def setParentItem(self, parent_item):
        super().setParentItem(parent_item)
        self._update_avoid()
Example #29
0
class FadingTipBox(FadingDialog):
    """ """
    def __init__(self,
                 parent,
                 opacity,
                 duration,
                 easing_curve,
                 tour=None,
                 color_top=None,
                 color_back=None,
                 combobox_background=None):
        super(FadingTipBox, self).__init__(parent, opacity, duration,
                                           easing_curve)
        self.holder = self.anim  # needed for qt to work
        self.parent = parent
        self.tour = tour

        self.frames = None
        self.offset_shadow = 0
        self.fixed_width = 300

        self.key_pressed = None

        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint
                            | Qt.WindowStaysOnTopHint)
        self.setModal(False)

        # Widgets
        def toolbutton(icon):
            bt = QToolButton()
            bt.setAutoRaise(True)
            bt.setIcon(icon)
            return bt

        self.button_close = toolbutton(ima.icon("tour.close"))
        self.button_home = toolbutton(ima.icon("tour.home"))
        self.button_previous = toolbutton(ima.icon("tour.previous"))
        self.button_end = toolbutton(ima.icon("tour.end"))
        self.button_next = toolbutton(ima.icon("tour.next"))
        self.button_run = QPushButton(_('Run code'))
        self.button_disable = None
        self.button_current = QToolButton()
        self.label_image = QLabel()

        self.label_title = QLabel()
        self.combo_title = QComboBox()
        self.label_current = QLabel()
        self.label_content = QLabel()

        self.label_content.setMinimumWidth(self.fixed_width)
        self.label_content.setMaximumWidth(self.fixed_width)

        self.label_current.setAlignment(Qt.AlignCenter)

        self.label_content.setWordWrap(True)

        self.widgets = [
            self.label_content, self.label_title, self.label_current,
            self.combo_title, self.button_close, self.button_run,
            self.button_next, self.button_previous, self.button_end,
            self.button_home, self.button_current
        ]

        arrow = get_image_path('hide.png')

        self.color_top = color_top
        self.color_back = color_back
        self.combobox_background = combobox_background
        self.stylesheet = '''QComboBox {{
                             padding-left: 5px;
                             background-color: {}
                             border-width: 0px;
                             border-radius: 0px;
                             min-height:20px;
                             max-height:20px;
                             }}

                             QComboBox::drop-down  {{
                             subcontrol-origin: padding;
                             subcontrol-position: top left;
                             border-width: 0px;
                             }}

                             QComboBox::down-arrow {{
                             image: url({});
                             }}

                             '''.format(self.combobox_background.name(), arrow)
        # Windows fix, slashes should be always in unix-style
        self.stylesheet = self.stylesheet.replace('\\', '/')

        self.setFocusPolicy(Qt.StrongFocus)
        for widget in self.widgets:
            widget.setFocusPolicy(Qt.NoFocus)
            widget.setStyleSheet(self.stylesheet)

        layout_top = QHBoxLayout()
        layout_top.addWidget(self.combo_title)
        layout_top.addStretch()
        layout_top.addWidget(self.button_close)
        layout_top.addSpacerItem(
            QSpacerItem(self.offset_shadow, self.offset_shadow))

        layout_content = QHBoxLayout()
        layout_content.addWidget(self.label_content)
        layout_content.addWidget(self.label_image)
        layout_content.addSpacerItem(QSpacerItem(5, 5))

        layout_run = QHBoxLayout()
        layout_run.addStretch()
        layout_run.addWidget(self.button_run)
        layout_run.addStretch()
        layout_run.addSpacerItem(
            QSpacerItem(self.offset_shadow, self.offset_shadow))

        layout_navigation = QHBoxLayout()
        layout_navigation.addWidget(self.button_home)
        layout_navigation.addWidget(self.button_previous)
        layout_navigation.addStretch()
        layout_navigation.addWidget(self.label_current)
        layout_navigation.addStretch()
        layout_navigation.addWidget(self.button_next)
        layout_navigation.addWidget(self.button_end)
        layout_navigation.addSpacerItem(
            QSpacerItem(self.offset_shadow, self.offset_shadow))

        layout = QVBoxLayout()
        layout.addLayout(layout_top)
        layout.addStretch()
        layout.addSpacerItem(QSpacerItem(15, 15))
        layout.addLayout(layout_content)
        layout.addLayout(layout_run)
        layout.addStretch()
        layout.addSpacerItem(QSpacerItem(15, 15))
        layout.addLayout(layout_navigation)
        layout.addSpacerItem(
            QSpacerItem(self.offset_shadow, self.offset_shadow))

        layout.setSizeConstraint(QLayout.SetFixedSize)

        self.setLayout(layout)

        self.set_funcs_before_fade_in([self._disable_widgets])
        self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus])
        self.set_funcs_before_fade_out([self._disable_widgets])

        self.setContextMenuPolicy(Qt.CustomContextMenu)

        # signals and slots
        # These are defined every time by the AnimatedTour Class

    def _disable_widgets(self):
        """ """
        for widget in self.widgets:
            widget.setDisabled(True)

    def _enable_widgets(self):
        """ """
        self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint
                            | Qt.WindowStaysOnTopHint)
        for widget in self.widgets:
            widget.setDisabled(False)

        if self.button_disable == 'previous':
            self.button_previous.setDisabled(True)
            self.button_home.setDisabled(True)
        elif self.button_disable == 'next':
            self.button_next.setDisabled(True)
            self.button_end.setDisabled(True)

    def set_data(self,
                 title,
                 content,
                 current,
                 image,
                 run,
                 frames=None,
                 step=None):
        """ """
        self.label_title.setText(title)
        self.combo_title.clear()
        self.combo_title.addItems(frames)
        self.combo_title.setCurrentIndex(step)
        #        min_content_len = max([len(f) for f in frames])
        #        self.combo_title.setMinimumContentsLength(min_content_len)

        # Fix and try to see how it looks with a combo box
        self.label_current.setText(current)
        self.button_current.setText(current)
        self.label_content.setText(content)
        self.image = image

        if image is None:
            self.label_image.setFixedHeight(1)
            self.label_image.setFixedWidth(1)
        else:
            extension = image.split('.')[-1]
            self.image = QPixmap(get_image_path(image), extension)
            self.label_image.setPixmap(self.image)
            self.label_image.setFixedSize(self.image.size())

        if run is None:
            self.button_run.setVisible(False)
        else:
            self.button_run.setDisabled(False)
            self.button_run.setVisible(True)

        # Refresh layout
        self.layout().activate()

    def set_pos(self, x, y):
        """ """
        self.x = ceil(x)
        self.y = ceil(y)
        self.move(QPoint(self.x, self.y))

    def build_paths(self):
        """ """
        geo = self.geometry()
        radius = 0
        shadow = self.offset_shadow
        x0, y0 = geo.x(), geo.y()
        width, height = geo.width() - shadow, geo.height() - shadow

        left, top = 0, 0
        right, bottom = width, height

        self.round_rect_path = QPainterPath()
        self.round_rect_path.moveTo(right, top + radius)
        self.round_rect_path.arcTo(right - radius, top, radius, radius, 0.0,
                                   90.0)
        self.round_rect_path.lineTo(left + radius, top)
        self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0)
        self.round_rect_path.lineTo(left, bottom - radius)
        self.round_rect_path.arcTo(left, bottom - radius, radius, radius,
                                   180.0, 90.0)
        self.round_rect_path.lineTo(right - radius, bottom)
        self.round_rect_path.arcTo(right - radius, bottom - radius, radius,
                                   radius, 270.0, 90.0)
        self.round_rect_path.closeSubpath()

        # Top path
        header = 36
        offset = 2
        left, top = offset, offset
        right = width - (offset)
        self.top_rect_path = QPainterPath()
        self.top_rect_path.lineTo(right, top + radius)
        self.top_rect_path.moveTo(right, top + radius)
        self.top_rect_path.arcTo(right - radius, top, radius, radius, 0.0,
                                 90.0)
        self.top_rect_path.lineTo(left + radius, top)
        self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0)
        self.top_rect_path.lineTo(left, top + header)
        self.top_rect_path.lineTo(right, top + header)

    def paintEvent(self, event):
        """ """
        self.build_paths()

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillPath(self.round_rect_path, self.color_back)
        painter.fillPath(self.top_rect_path, self.color_top)
        painter.strokePath(self.round_rect_path, QPen(Qt.gray, 1))

        # TODO: Build the pointing arrow?

    def keyReleaseEvent(self, event):
        """ """
        key = event.key()
        self.key_pressed = key

        keys = [
            Qt.Key_Right, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Escape,
            Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Home, Qt.Key_End,
            Qt.Key_Menu
        ]

        if key in keys:
            if not self.is_fade_running():
                self.sig_key_pressed.emit()

    def mousePressEvent(self, event):
        """override Qt method"""
        # Raise the main application window on click
        self.parent.raise_()
        self.raise_()

        if event.button() == Qt.RightButton:
            pass


#            clicked_widget = self.childAt(event.x(), event.y())
#            if clicked_widget == self.label_current:
#            self.context_menu_requested(event)

    def focusOutEvent(self, event):
        """Override Qt method."""
        # To be used so tips do not appear outside spyder
        self.tour.lost_focus()

    def context_menu_requested(self, event):
        """ """
        pos = QPoint(event.x(), event.y())
        menu = QMenu(self)

        actions = []
        action_title = create_action(self, _('Go to step: '), icon=QIcon())
        action_title.setDisabled(True)
        actions.append(action_title)
        #        actions.append(create_action(self, _(': '), icon=QIcon()))

        add_actions(menu, actions)

        menu.popup(self.mapToGlobal(pos))

    def reject(self):
        """Qt method to handle escape key event"""
        if not self.is_fade_running():
            key = Qt.Key_Escape
            self.key_pressed = key
            self.sig_key_pressed.emit()
Example #30
0
class RectangularRegion(ChartItem):
    """ Rectangular overlay, that (optionally) can be resized by handles.

    TODO:
      * Notification framework
      * Modifiers to allow for more flexible mouse interactions
    """
    def __init__(self, x, y, width=1, height=1, rotation=0, parent=None):
        """ Constructor.

        :param x: Initial x position of ROIs center.
        :param y: Initial y position of ROIs center.
        :param width: Initial width
        :param height: Initial height
        :param rotation: Initial rotation in radians
        :param parent: Optional parent item.
        """
        super(RectangularRegion, self).__init__(parent)

        self.setFlags(QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemIsFocusable
                      | QGraphicsItem.ItemSendsGeometryChanges)

        # self.setHandlesChildEvents(False)
        # self.setFiltersChildEvents(True)
        self.__in_move = False

        self._path = QPainterPath()
        self.pen = QPen(QBrush(QColor(161, 0, 161, 255)), 1.0, Qt.SolidLine)
        self.pen.setCosmetic(True)
        self.brush = QBrush(QColor(255, 255, 255, 40))

        self.state = RoiState()
        self.state.pos = QPointF(x, y)
        self.state.w0 = width
        self.state.w1 = width
        self.state.h0 = height
        self.state.h1 = height

        self.state.rotation = rotation

        self.setPos(self.state.pos)
        self.updatePath()

        self._handles = []

    @property
    def handles(self):
        """ Returns all handles which are attached to the ROI.

        :return: list
        """
        return self._handles

    def addHandle(self, handle):
        """ Adds a handle to the ROI.

        :param handle: Resize or rotate handle
        """
        handle.setParentItem(self)
        # self.addToGroup(handle)
        self.handles.append(handle)
        handle.updatePosition()

    def removeHandle(self, handle):
        """ Removes the given handle from the ROI.

        :param handle: Handle
        :return:
        """
        if handle not in self.handles:
            _log.warning("Handle not part of ROI.")
            return

        self.handles.remove(handle)
        # self.removeFromGroup(handle)
        self.scene().removeItem(handle)

    def boundingRect(self):
        return self._path.boundingRect()

    def updatePath(self):
        p0 = Vec2(self.state.w0, self.state.h0)
        p1 = Vec2(-self.state.w1, self.state.h0)
        p2 = Vec2(-self.state.w1, -self.state.h1)
        p3 = Vec2(self.state.w0, -self.state.h1)

        p0t = p0.rotate(self.state.rotation)
        p1t = p1.rotate(self.state.rotation)
        p2t = p2.rotate(self.state.rotation)
        p3t = p3.rotate(self.state.rotation)

        self._path = QPainterPath()
        self._path.moveTo(p0t.x, p0t.y)
        self._path.lineTo(p1t.x, p1t.y)
        self._path.lineTo(p2t.x, p2t.y)
        self._path.lineTo(p3t.x, p3t.y)
        self._path.closeSubpath()

        self.prepareGeometryChange()

    def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None):
        p.setRenderHint(QPainter.Antialiasing)
        p.setPen(self.pen)
        p.setBrush(self.brush)
        p.drawPath(self._path)

        p.setBrush(Qt.transparent)
        p.drawLine(QLineF(-0.5, 0, 0.5, 0))
        p.drawLine(QLineF(0, -0.5, 0, 0.5))
        p.drawEllipse(QPointF(0, 0), 0.25, 0.25)

    def mousePressEvent(self, e):
        # !!!F*****g leason learned, call super to avoid weird jumps in position!!!
        super(RectangularRegion, self).mousePressEvent(e)
        self.__in_move = True

    def mouseReleaseEvent(self, e):
        super(RectangularRegion, self).mouseReleaseEvent(e)
        self.__in_move = False

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange and self.__in_move:
            old_pos = self.pos()
            new_pos = value  # .toPointF()

            delta = old_pos - new_pos
            _log.debug("Delta: {}".format(delta))

            self.state.pos = new_pos
            value = new_pos

            for handle in self.handles:
                handle.updatePosition()

        return super(RectangularRegion, self).itemChange(change, value)

    def rotation(self):
        """ Override takes rotation from the state instead of items transformation.

        :return: rotation in degrees
        """
        return self.state.rotation * 180 / np.pi

    def setRotation(self, degree):
        """ Override to propagate rotation to state instead of applying it to the items transform

        :param degree: Rotation in degrees
        """
        self.state.rotation = (degree % 360) * np.pi / 180.0

        for h in self.handles:
            h.updatePosition()

        self.updatePath()