def updateArrowHead(self):
        line = self.line()
        if not self.isBezier():
            if self._reversed:
                u = line.p1() - line.p2()
            else:
                u = line.p2() - line.p1()
        else:
            if self._reversed:
                u = self._points[0].pos() - self._points[1].pos()
            else:
                u = self._points[-1].pos() - self._points[-2].pos()

        mag_u = mag2D(u)
        if mag_u == 0.0:
            self._arrowHead = QPainterPath()
            return
        u /= mag_u
        v = QPointF(-u.y(), u.x())  # perp vector
        path = QPainterPath()
        if self._reversed:
            tip = line.p1()
        else:
            tip = line.p2()
        size = self.arrowHeadSize()
        p = tip - (u + v) * size
        q = tip + (v - u) * size
        r = tip - u * size
        path.moveTo(p)
        path.quadTo((p + tip + r) / 3, tip)
        path.quadTo((q + tip + r) / 3, q)
        self._arrowHead = path
示例#2
0
 def update(self, eventPos, fase, point=None):
     # If user is setting the final point
     if fase == 1:
         path = QPainterPath()
         path.moveTo(self.initialPoint.position)
         path.lineTo(eventPos)
         self.setPath(path)
         if point:
             self.finalPoint = point
     # If user is setting ctrlPoint1
     elif fase == 2:
         path = QPainterPath()
         path.moveTo(self.initialPoint.position)
         path.quadTo(eventPos, self.finalPoint.position)
         self.setPath(path)
         if point:
             self.ctrlPoint1 = point
     # If user is finishing the path (setting ctrlPoint2)
     elif fase == 3:
         path = QPainterPath()
         path.moveTo(self.initialPoint.position)
         path.cubicTo(self.ctrlPoint1.position, eventPos,
                      self.finalPoint.position)
         self.setPath(path)
         if point:
             self.ctrlPoint2 = point
示例#3
0
def _pointWithinThreshold(x, y, curve, eps):
    """
    See whether *(x, y)* is within *eps* of *curve*.
    """
    path = QPainterPath()
    path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps)
    curvePath = QPainterPath()
    if curve[-1].segmentType == "curve":
        p1, p2, p3, p4 = curve
        curvePath.moveTo(p1.x, p1.y)
        curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)
        curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y)
    else:
        first = curve[0]
        curvePath.moveTo(first.x, first.y)
        # PACK for fontTools
        pts = []
        for pt in curve:
            pts.append((pt.x, pt.y))
        # draw
        for pt1, pt2 in decomposeQuadraticSegment(pts[1:]):
            curvePath.quadTo(*pt1+pt2)
        for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))):
            curvePath.quadTo(*pt1+pt2)
    return path.intersects(curvePath)
示例#4
0
    def get_path(self, clickedPoints) -> QPainterPath:
        m_path = QPainterPath()
        self.clickedPoints = clickedPoints

        if len(self.clickedPoints) < 3:
            print("still have 2 points or less.")
            return m_path

        pt1 = QPointF()
        pt2 = QPointF()

        for i in range(len(self.clickedPoints) - 1):
            pt1 = self.get_line_start(i)

            if i == 0:
                m_path.moveTo(pt1)
            else:
                m_path.quadTo(clickedPoints[i], pt1)

            # pt2 = self.getLineEnd(i)
            # mPath.lineTo(pt2)

        # pt1 = self.getLineStart(0)
        # mPath.quadTo(clickedPoints[0], pt1)

        return m_path
示例#5
0
    def drawGlyph(self,
                  scene,
                  glyph,
                  offsetX=0,
                  offsetY=0,
                  color=(255, 255, 255)):
        path = QPainterPath()
        path.setFillRule(Qt.WindingFill)
        for c in self.decomposedPaths(glyph):
            segs = c.segments
            path.moveTo(segs[-1].points[-1].x, segs[-1].points[-1].y)
            for seg in segs:
                tuples = [(a.x, a.y) for a in seg.points]
                flattuples = list(sum(tuples, ()))
                if len(tuples) == 2:
                    path.quadTo(*flattuples)
                elif len(tuples) == 3:
                    path.cubicTo(*flattuples)
                else:
                    path.lineTo(*flattuples)

        line = QGraphicsPathItem()
        line.setBrush(QColor(*color))
        p = QPen()
        p.setStyle(Qt.NoPen)
        line.setPen(p)
        line.setPath(path)
        reflect = QTransform(1, 0, 0, -1, 0, 0)
        reflect.translate(offsetX, offsetY)
        # print(f"Drawing {glyph} at offset {offsetX} {offsetY}")
        line.setTransform(reflect)
        scene.addItem(line)
示例#6
0
def _pointWithinThreshold(x, y, curve, eps):
    """
    See whether *(x, y)* is within *eps* of *curve*.
    """
    path = QPainterPath()
    path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps)
    curvePath = QPainterPath()
    if curve[-1].segmentType == "curve":
        p1, p2, p3, p4 = curve
        curvePath.moveTo(p1.x, p1.y)
        curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)
        curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y)
    else:
        first = curve[0]
        curvePath.moveTo(first.x, first.y)
        # PACK for fontTools
        pts = []
        for pt in curve:
            pts.append((pt.x, pt.y))
        # draw
        for pt1, pt2 in decomposeQuadraticSegment(pts[1:]):
            curvePath.quadTo(*pt1 + pt2)
        for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))):
            curvePath.quadTo(*pt1 + pt2)
    return path.intersects(curvePath)
示例#7
0
def _insertGen( path: QPainterPath,
                start: QPointF,
                c1: QPointF,
                p1: QPointF,
                c2: QPointF):
    path.moveTo(start)
    path.quadTo(c1, p1)
    path.quadTo(c2, start)
示例#8
0
    def triangle_pellet(self, painter: QPainter, pellet_size: float):
        """A pellet that is pointy and triangular (1st in logo)"""
        pellet_size *= 1.5

        pellet = QPainterPath()
        pellet.setFillRule(Qt.WindingFill)
        pellet.quadTo(0.9 * pellet_size, 0.5 * pellet_size, 0, pellet_size)
        pellet.quadTo(-0.5 * pellet_size, 0.4 * pellet_size, 0, 0)
        painter.drawPath(pellet)
示例#9
0
    def round_pellet(self, painter: QPainter, pellet_size):
        """A pellet that is round but not a circle (3rd in the logo)."""
        pellet_size *= 1.3

        pellet = QPainterPath()
        pellet.setFillRule(Qt.WindingFill)

        for c in [1, -1]:
            pellet.quadTo(c * pellet_size * 0.8, pellet_size * 0.9, 0, pellet_size if c != -1 else 0)

        painter.drawPath(pellet)
示例#10
0
文件: edge.py 项目: leedaniil/Grapher
    def _get_path(self):
        path = QPainterPath()
        if not self.line().length():
            return path

        path.moveTo(self.line().p1())
        if self.index:
            path.quadTo(self.quad_center, self.line().p2())
        else:
            path.lineTo(self.line().p2())
        return path
示例#11
0
    def dip_pellet(self, painter: QPainter, pellet_size):
        """A pellet that has a dip in the middle (4th in the logo)."""
        pellet_size *= 1.2

        pellet = QPainterPath()
        pellet.setFillRule(Qt.WindingFill)

        for c in [1, -1]:
            pellet.quadTo(c * pellet_size, pellet_size * 1.4, 0, pellet_size if c != -1 else 0)

        painter.drawPath(pellet)
示例#12
0
    def activateNeighbor(self,
                         active_prexoveritem: 'PreXoverItem',
                         shortcut: str = None):
        """Draws a quad line starting from the item5p to the item3p.
        To be called with whatever the active_prexoveritem is for the parts
        `active_base`.

        Args:
            active_prexoveritem: Description
            shortcut: Default is None
        """
        if self._getActiveTool().methodPrefix() != "selectTool":
            return

        if self.is3p and not active_prexoveritem.is3p:
            item5p = active_prexoveritem
            item3p = self
        elif not self.is3p and active_prexoveritem.is3p:
            item5p = self
            item3p = active_prexoveritem
        else:
            return

        same_parity = self.is_fwd == active_prexoveritem.is_fwd

        p1 = item5p._tick_marks.scenePos() + item5p.exit_pos
        p2 = item3p._tick_marks.scenePos() + item3p.exit_pos

        c1 = QPointF()

        # case 1: same parity
        if same_parity:
            dy = abs(p2.y() - p1.y())
            c1.setX(p1.x() + _X_SCALE * dy)
            c1.setY(0.5 * (p1.y() + p2.y()))
        # case 2: different parity
        else:
            if item3p.is_fwd:
                c1.setX(p1.x() - _X_SCALE * abs(p2.y() - p1.y()))
            else:
                c1.setX(p1.x() + _X_SCALE * abs(p2.y() - p1.y()))
            c1.setY(0.5 * (p1.y() + p2.y()))

        pp = QPainterPath()
        pp.moveTo(self._tick_marks.mapFromScene(p1))
        pp.quadTo(self._tick_marks.mapFromScene(c1),
                  self._tick_marks.mapFromScene(p2))
        # pp.cubicTo(c1, c2, self._tick_marks.mapFromScene(p2))
        self._bond_item.setPath(pp)
        self._bond_item.show()
示例#13
0
    def activateNeighbor(self,  active_prexoveritem: 'PreXoverItem',
                                shortcut: str = None):
        """Draws a quad line starting from the item5p to the item3p.
        To be called with whatever the active_prexoveritem is for the parts
        `active_base`.

        Args:
            active_prexoveritem: Description
            shortcut: Default is None
        """
        if self._getActiveTool().methodPrefix() != "selectTool":
            return

        if self.is3p and not active_prexoveritem.is3p:
            item5p = active_prexoveritem
            item3p = self
        elif not self.is3p and active_prexoveritem.is3p:
            item5p = self
            item3p = active_prexoveritem
        else:
            return

        same_parity = self.is_fwd == active_prexoveritem.is_fwd

        p1 = item5p._tick_marks.scenePos() + item5p.exit_pos
        p2 = item3p._tick_marks.scenePos() + item3p.exit_pos

        c1 = QPointF()

        # case 1: same parity
        if same_parity:
            dy = abs(p2.y() - p1.y())
            c1.setX(p1.x() + _X_SCALE * dy)
            c1.setY(0.5 * (p1.y() + p2.y()))
        # case 2: different parity
        else:
            if item3p.is_fwd:
                c1.setX(p1.x() - _X_SCALE * abs(p2.y() - p1.y()))
            else:
                c1.setX(p1.x() + _X_SCALE * abs(p2.y() - p1.y()))
            c1.setY(0.5 * (p1.y() + p2.y()))

        pp = QPainterPath()
        pp.moveTo(self._tick_marks.mapFromScene(p1))
        pp.quadTo(self._tick_marks.mapFromScene(c1),
                  self._tick_marks.mapFromScene(p2))
        # pp.cubicTo(c1, c2, self._tick_marks.mapFromScene(p2))
        self._bond_item.setPath(pp)
        self._bond_item.show()
示例#14
0
    def draw_background(self, painter):

        self.initCoordinateSystem(painter)

        glass = QPainterPath()
        glass.moveTo(12.5, 267.5)
        glass.quadTo(12.5, 263.0, 7.5, 257.0)

        glass.lineTo(7.5, 25.0)
        glass.quadTo(7.5, 12.5, 0, 12.5)
        glass.quadTo(-7.5, 12.5, -7.5, 25.0)
        glass.lineTo(-7.5, 257.0)

        glass.quadTo(-12.5, 263.0, -12.5, 267.5)
        glass.quadTo(-12.5, 278.0, 0.0, 280.0)
        glass.quadTo(12.5, 278.0, 12.5, 267.5)

        linearGrad = QLinearGradient(QPointF(-2.0, 0.0), QPointF(12.5, 0.0))
        linearGrad.setSpread(QGradient.ReflectSpread)
        linearGrad.setColorAt(1.0, QColor(0, 150, 255, 170))
        linearGrad.setColorAt(0.0, QColor(255, 255, 255, 0))

        painter.setBrush(QBrush(linearGrad))
        painter.setPen(Qt.black)
        painter.drawPath(glass)

        pen = QPen()

        for i in range(33):
            pen.setWidthF(1.0)
            length = 12
            if i % 4:
                length = 8
                pen.setWidthF(0.75)
            if i % 2:
                length = 5
                pen.setWidthF(0.5)

            painter.setPen(pen)
            painter.drawLine(-7, 28 + 7 * i, -7 + length, 28 + 7 * i)

        painter.setFont(self.mDigitFont)
        for i in range(9):
            val = self.mPointer.minimal() + i * (self.mPointer.maximal() -
                                                 self.mPointer.minimal()) / 8.0
            Size = painter.fontMetrics().size(Qt.TextSingleLine, str(val))
            painter.drawText(QPointF(10, 252 - i * 28 + Size.width() / 4.0),
                             str(val))
示例#15
0
 def updateConnector(self,
                     item: QGraphicsPathItem,
                     p1: QPointF,
                     p2: QPointF,
                     select: bool = True):
     path = QPainterPath(p1)
     path.quadTo(p1 + QPointF(-15, 0), (p1 + p2) * 0.5)
     path.quadTo(p2 + QPointF(15, 0), p2)
     if item is None:
         item = self.nodesScene.addPath(path)
     else:
         item.setPath(path)
     item.setZValue(-1)
     if select:
         item.setFlag(QGraphicsItem.ItemIsSelectable)
     return item
示例#16
0
 def shape(self):
     if self.ctrlPoint:
         path = QPainterPath()
         path.moveTo(
             self.path().pointAtPercent(4 / self.path().length()).x(),
             self.path().pointAtPercent(4 / self.path().length()).y())
         path.quadTo(
             self.ctrlPoint.position.x(), self.ctrlPoint.position.y(),
             self.path().pointAtPercent(1 - 4 / self.path().length()).x(),
             self.path().pointAtPercent(1 - 4 / self.path().length()).y())
         path.quadTo(
             self.ctrlPoint.position.x(), self.ctrlPoint.position.y(),
             self.path().pointAtPercent(4 / self.path().length()).x(),
             self.path().pointAtPercent(4 / self.path().length()).y())
         return path
     else:
         return super(quadraticEdge, self).shape()
示例#17
0
    def _draw(self, painter: QPainter, width: int, height: int):
        self.x = self.flower_center_x(width) * smoothen_curve(
            self.get_age_coefficient())
        self.y = self.flower_center_y(height) * smoothen_curve(
            self.get_age_coefficient())

        painter.setPen(
            QPen(Color.green,
                 self.stem_width * smoothen_curve(self.get_age_coefficient())))

        # draw the stem
        path = QPainterPath()
        path.quadTo(0, self.y * 0.6, self.x, self.y)
        painter.drawPath(path)

        # draw the leaves
        for position, coefficient, rotation in self.leafs:
            painter.save()

            # find the point on the stem and rotate the leaf accordingly
            painter.translate(path.pointAtPercent(position))
            painter.rotate(degrees(rotation))

            # rotate according to where the flower is leaning towards
            if self.y != 0:
                painter.rotate(-degrees(sin(self.x / self.y)))

            # make it so both leaves are facing the same direction
            if rotation < 0:
                painter.scale(-1, 1)

            painter.setBrush(QBrush(Color.green))
            painter.setPen(QPen(0))

            # draw the leaf
            leaf = QPainterPath()
            leaf.setFillRule(Qt.WindingFill)
            ls = self.leaf_size(width) * smoothen_curve(
                self.get_age_coefficient())**2 * coefficient
            leaf.quadTo(0.4 * ls, 0.5 * ls, 0, ls)
            leaf.cubicTo(0, 0.5 * ls, -0.4 * ls, 0.4 * ls, 0, 0)
            painter.drawPath(leaf)

            painter.restore()
示例#18
0
def arrow_path_concave(line, width):
    """
    Return a :class:`QPainterPath` of a pretty looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))

    start, end = baseline.p1(), baseline.p2()
    mid = (start + end) / 2.0
    normal = QLineF.fromPolar(1.0, baseline.angle() + 90).p2()

    path.moveTo(start)
    path.lineTo(start + (normal * width / 4.0))

    path.quadTo(mid + (normal * width / 4.0), end + (normal * width / 1.5))

    path.lineTo(end - (normal * width / 1.5))
    path.quadTo(mid - (normal * width / 4.0), start - (normal * width / 4.0))
    path.closeSubpath()

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        baseline.p2(), p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
示例#19
0
class QMarkItem(QGraphicsPathItem):
    def __init__(self, pt, style, parent=None):
        super().__init__()
        self.saveable = True
        self.pt = pt
        self.path = QPainterPath()
        # Draw a ?-mark with barycentre under mouseclick
        self.path.moveTo(pt.x() - 6, pt.y() - 10)
        self.path.quadTo(pt.x() - 6, pt.y() - 15, pt.x(), pt.y() - 15)
        self.path.quadTo(pt.x() + 6, pt.y() - 15, pt.x() + 6, pt.y() - 10)
        self.path.cubicTo(pt.x() + 6,
                          pt.y() - 1, pt.x(),
                          pt.y() - 7, pt.x(),
                          pt.y() + 2)
        self.path.moveTo(pt.x(), pt.y() + 12)
        self.path.lineTo(pt.x(), pt.y() + 10)
        self.setPath(self.path)
        self.restyle(style)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)

    def restyle(self, style):
        self.normal_thick = 3 * style["pen_width"] / 2
        self.setPen(QPen(style["annot_color"], self.normal_thick))

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange and self.scene():
            command = CommandMoveItem(self, value)
            self.scene().undoStack.push(command)
        return super().itemChange(change, value)

    def pickle(self):
        return ["QMark", self.pt.x() + self.x(), self.pt.y() + self.y()]

    def paint(self, painter, option, widget):
        if not self.scene().itemWithinBounds(self):
            # paint a bounding rectangle out-of-bounds warning
            painter.setPen(QPen(QColor(255, 165, 0), 8))
            painter.setBrush(QBrush(QColor(255, 165, 0, 128)))
            painter.drawRoundedRect(option.rect, 10, 10)
        # paint the normal item with the default 'paint' method
        super().paint(painter, option, widget)
示例#20
0
class QMarkItem(QGraphicsPathItem):
    # Very similar to the arrowitem, but careful drawing the "?"
    def __init__(self, pt, parent=None):
        super(QMarkItem, self).__init__()
        self.saveable = True
        self.animator = [parent]
        self.animateFlag = False
        self.pt = pt
        self.path = QPainterPath()
        # Draw a ?-mark with barycentre under mouseclick
        self.path.moveTo(pt.x() - 6, pt.y() - 10)
        self.path.quadTo(pt.x() - 6, pt.y() - 15, pt.x(), pt.y() - 15)
        self.path.quadTo(pt.x() + 6, pt.y() - 15, pt.x() + 6, pt.y() - 10)
        self.path.cubicTo(pt.x() + 6,
                          pt.y() - 1, pt.x(),
                          pt.y() - 7, pt.x(),
                          pt.y() + 2)
        self.path.moveTo(pt.x(), pt.y() + 12)
        self.path.lineTo(pt.x(), pt.y() + 10)
        self.setPath(self.path)
        self.setPen(QPen(Qt.red, 3))
        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange and self.scene():
            command = CommandMoveItem(self, value)
            self.scene().undoStack.push(command)
        return QGraphicsPathItem.itemChange(self, change, value)

    def pickle(self):
        return ["QMark", self.pt.x() + self.x(), self.pt.y() + self.y()]

    def paint(self, painter, option, widget):
        if not self.collidesWithItem(self.scene().underImage,
                                     mode=Qt.ContainsItemShape):
            # paint a bounding rectangle out-of-bounds warning
            painter.setPen(QPen(QColor(255, 165, 0), 8))
            painter.setBrush(QBrush(QColor(255, 165, 0, 128)))
            painter.drawRoundedRect(option.rect, 10, 10)
        # paint the normal item with the default 'paint' method
        super(QMarkItem, self).paint(painter, option, widget)
 def goOn(self):
     self.anim = QPropertyAnimation(self.mascot, b"pos")
     self.mascotFlip.hide()
     self.mascotGif.start()
     self.mascot.show()
     path = QPainterPath()
     path.moveTo(-70, 410)
     for i in range(self.step):
         path.quadTo(
             QPointF(
                 self.xRange / self.step * i - 70 +
                 (self.xRange / self.step / 2), 410),
             QPointF((self.xRange / self.step) * i - 70 +
                     (self.xRange / self.step), 430))
     vals = [p / 100 for p in range(0, 101)]
     self.anim.setDuration(self.duration)
     for i in vals:
         self.anim.setKeyValueAt(i, path.pointAtPercent(i))
     self.anim.start()
     self.anim.finished.connect(self.goFlip)
示例#22
0
def to_qpainter_path(paths: Iterable[Path], extrusion: 'Vertex' = Z_AXIS):
    """ Convert the given `paths` into a :class:`PyQt5.QtGui.QPainterPath`
    object.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The :class:`QPainterPath` is a 2D object with :ref:`OCS`
    coordinates and the z-elevation is lost. (requires PyQt5)

    Args:
        paths: iterable of :class:`Path` objects
        extrusion: extrusion vector for all paths

    Returns:
        `QPainterPath`_ in OCS!

    .. versionadded:: 0.16

    """
    from PyQt5.QtGui import QPainterPath
    from PyQt5.QtCore import QPointF
    if not extrusion.isclose(Z_AXIS):
        paths = tools.transform_paths_to_ocs(paths, OCS(extrusion))
    else:
        paths = list(paths)
    if len(paths) == 0:
        raise ValueError('one or more paths required')

    def qpnt(v: Vec3):
        return QPointF(v.x, v.y)

    qpath = QPainterPath()
    for path in paths:
        qpath.moveTo(qpnt(path.start))
        for cmd in path:
            if cmd.type == Command.LINE_TO:
                qpath.lineTo(qpnt(cmd.end))
            elif cmd.type == Command.CURVE3_TO:
                qpath.quadTo(qpnt(cmd.ctrl), qpnt(cmd.end))
            elif cmd.type == Command.CURVE4_TO:
                qpath.cubicTo(qpnt(cmd.ctrl1), qpnt(cmd.ctrl2), qpnt(cmd.end))
    return qpath
示例#23
0
    def paintEvent(self, event):
        # Initializing QPainter
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)
        sidebar_rect = self.geometry()
        # Gradient
        gradient = QLinearGradient(0, 0, sidebar_rect.width(), 0)
        gradient.setColorAt(0.0, self.color_gradient_left)
        gradient.setColorAt(1.0, self.color_gradient_right)

        qp.setBrush(QBrush(gradient))
        # qp.setPen(Qt.white)
        qp.drawRect(0, 0, sidebar_rect.width(), sidebar_rect.height())

        # Glass highlight
        qp.setBrush(QBrush(Qt.white))
        qp.setPen(QPen(QBrush(Qt.white), 0.01))
        qp.setOpacity(0.1)

        qppath = QPainterPath()
        qppath.moveTo(sidebar_rect.width() * 0.2, 0)
        qppath.quadTo(sidebar_rect.width() * 0.3, sidebar_rect.height()
                      * 0.5, sidebar_rect.width() * 0.2, sidebar_rect.height() - 1)
        qppath.lineTo(0, sidebar_rect.height())
        qppath.lineTo(0, 0)
        qp.setClipPath(qppath)
        qp.drawRect(1, 1, sidebar_rect.width() - 1, sidebar.height() - 1)

        # Left border highlight
        qp.setOpacity(1.0)
        gradient = QLinearGradient(0, 0, 2, 0)
        gradient.setColorAt(0.0, QColor(255, 255, 255, 80))
        gradient.setColorAt(1.0, QColor(0, 0, 0, 0))

        qp.setBrush(QBrush(gradient))
        # qp.setPen(Qt.transparent)
        qp.drawRect(0, 0, 8, sidebar_rect.height())

        qp.end()
示例#24
0
    def randomWalk(self, image):
        """
        actual calculations
        :param image: bitmap to squigglify
        :return:
        """
        self.removeOldGraphicsItems()
        group = QGraphicsItemGroup()
        no_of_walks = self.parent.noOfWalksWalkify.value()
        coordinates = {}
        self.applyThreshold(image)
        for w in range(no_of_walks):
            x, y = self.find_darkest(image)
            x, y, color = self.find_darkest_neighbor(image, x, y)
            coordinates[w] = np.array([[x, y]])
            no_of_line_segments = self.parent.noOfLineSegmentsWalkify.value()
            adjustbrightness = self.parent.localBrightnessAdjustmentWalkify.value(
            )
            stroke_width = self.parent.lineWidthWalkify.value()
            for s in range(0, no_of_line_segments):
                dx, dy, dc = self.find_darkest_neighbor(image, x, y)
                self.lighten_area_around(image, adjustbrightness, dx, dy)
                x, y = dx, dy
                coordinates[w] = np.append(coordinates[w], [[x, y]], axis=0)

        for w in range(no_of_walks):
            coordinates[w] = simplify_coords(
                coordinates[w],
                self.parent.polylineSimplificationToleranceWalkify.value())

        for w in range(no_of_walks):
            path = QPainterPath()
            in_the_middle_of_a_quad = False
            for idx, c in enumerate(coordinates[w]):
                quad = self.parent.useSmootherShapesWalkify.checkState(
                ) == Qt.Checked
                if not quad:
                    if idx == 0:
                        path.moveTo(coordinates[w][idx][0],
                                    coordinates[w][idx][1])
                    else:
                        path.lineTo(coordinates[w][idx][0],
                                    coordinates[w][idx][1])
                else:
                    if idx == 0:
                        path.moveTo(coordinates[w][idx][0],
                                    coordinates[w][idx][1])
                    elif idx % 2 == 1:
                        middlex, middley = coordinates[w][idx][0], coordinates[
                            w][idx][1]
                        in_the_middle_of_a_quad = True
                    else:
                        path.quadTo(middlex, middley, coordinates[w][idx][0],
                                    coordinates[w][idx][1])
                        in_the_middle_of_a_quad = False

            if in_the_middle_of_a_quad:
                path.lineTo(middlex, middley)

            item = QGraphicsPathItem(path)
            pen = QPen()
            pen.setWidth(stroke_width)
            item.setPen(pen)
            group.addToGroup(item)

        self.addNewGraphicsItems(group)
示例#25
0
    def _updatePath(self, strand5p):
        """
        Draws a quad curve from the edge of the fromBase
        to the top or bottom of the toBase (q5), and
        finally to the center of the toBase (toBaseEndpoint).

        If floatPos!=None, this is a floatingXover and floatPos is the
        destination point (where the mouse is) while toHelix, toIndex
        are potentially None and represent the base at floatPos.

        Args:
            strand5p (TYPE): Description
        """
        group = self.group()
        self.tempReparent()

        node3 = self._node3
        node5 = self._node5

        bw = _BASE_WIDTH

        parent = self.partItem()

        vhi5 = self._virtual_helix_item
        pt5 = vhi5.mapToItem(parent, *node5.point())

        n5_is_forward = node5.is_forward

        vhi3 = node3.virtualHelixItem()
        pt3 = vhi3.mapToItem(parent, *node3.point())

        n3_is_forward = node3.is_forward
        same_strand = (n5_is_forward == n3_is_forward) and (vhi3 == vhi5)
        same_parity = n5_is_forward == n3_is_forward

        # Enter/exit are relative to the direction that the path travels
        # overall.
        five_enter_pt = pt5 + QPointF(0 if n5_is_forward else 1, .5) * bw
        five_center_pt = pt5 + QPointF(.5, .5) * bw
        # five_exit_pt = pt5 + QPointF(.85 if n5_is_forward else .15, 0 if n5_is_forward else 1)*bw
        five_exit_pt = pt5 + QPointF(.5 if n5_is_forward else .5,
                                     0 if n5_is_forward else 1) * bw

        # three_enter_pt = pt3 + QPointF(.15 if n3_is_forward else .85, 0 if n3_is_forward else 1)*bw
        three_enter_pt = pt3 + QPointF(.5 if n3_is_forward else .5,
                                       0 if n3_is_forward else 1) * bw
        three_center_pt = pt3 + QPointF(.5, .5) * bw
        three_exit_pt = pt3 + QPointF(1 if n3_is_forward else 0, .5) * bw

        c1 = QPointF()
        # case 1: same strand
        if same_strand:
            dx = abs(three_enter_pt.x() - five_exit_pt.x())
            c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x()))
            if n5_is_forward:
                c1.setY(five_exit_pt.y() - _Y_SCALE * dx)
            else:
                c1.setY(five_exit_pt.y() + _Y_SCALE * dx)
        # case 2: same parity
        elif same_parity:
            dy = abs(three_enter_pt.y() - five_exit_pt.y())
            c1.setX(five_exit_pt.x() + _X_SCALE * dy)
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))
        # case 3: different parity
        else:
            if n5_is_forward:
                c1.setX(five_exit_pt.x() -
                        _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y()))
            else:
                c1.setX(five_exit_pt.x() +
                        _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y()))
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))

        # Construct painter path
        painterpath = QPainterPath()
        painterpath.moveTo(five_enter_pt)
        painterpath.lineTo(five_center_pt)
        painterpath.lineTo(five_exit_pt)

        # The xover5's non-crossing-over end (3') has a connection
        painterpath.quadTo(c1, three_enter_pt)
        painterpath.lineTo(three_center_pt)
        painterpath.lineTo(three_exit_pt)

        tempR = painterpath.boundingRect()
        tempR.adjust(-bw / 2, 0, bw, 0)
        self._click_area.setRect(tempR)
        self.setPath(painterpath)
        node3.updatePositionAndAppearance()
        node5.updatePositionAndAppearance()

        if group:
            group.addToGroup(self)

        self._updateColor(strand5p)
示例#26
0
    def updateFloatPath(self, point=None):
        """
        Draws a quad curve from the edge of the fromBase
        to the top or bottom of the toBase (q5), and
        finally to the center of the toBase (toBaseEndpoint).

        If floatPos!=None, this is a floatingXover and floatPos is the
        destination point (where the mouse is) while toHelix, toIndex
        are potentially None and represent the base at floatPos.

        Args:
            point (None, optional): Description

        """
        node3 = self._node3
        node5 = self._node5

        bw = _BASE_WIDTH

        vhi5 = self._virtual_helix_item
        nucleicacid_part_item = vhi5.partItem()
        pt5 = vhi5.mapToItem(nucleicacid_part_item, *node5.floatPoint())

        n5_is_forward = node5.is_forward

        # Enter/exit are relative to the direction that the path travels
        # overall.
        five_enter_pt = pt5 + QPointF(0 if n5_is_forward else 1, .5)*bw
        five_center_pt = pt5 + QPointF(.5, .5)*bw
        five_exit_pt = pt5 + QPointF(.5, 0 if n5_is_forward else 1)*bw

        vhi3 = node3.virtualHelixItem()

        if point:
            pt3 = point
            n3_is_forward = True
            same_strand = False
            same_parity = False
            three_enter_pt = three_center_pt = three_exit_pt = pt3
        else:
            pt3 = vhi3.mapToItem(nucleicacid_part_item, *node3.point())
            n3_is_forward = node3.is_forward
            same_strand = (n5_is_forward == n3_is_forward) and vhi3 == vhi5
            same_parity = n5_is_forward == n3_is_forward

            three_enter_pt = pt3 + QPointF(.5, 0 if n3_is_forward else 1)*bw
            three_center_pt = pt3 + QPointF(.5, .5)*bw
            three_exit_pt = pt3 + QPointF(1 if n3_is_forward else 0, .5)*bw

        c1 = QPointF()
        # case 1: same strand
        if same_strand:
            dx = abs(three_enter_pt.x() - five_exit_pt.x())
            c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x()))
            if n5_is_forward:
                c1.setY(five_exit_pt.y() - _yScale * dx)
            else:
                c1.setY(five_exit_pt.y() + _yScale * dx)
            # case 2: same parity
        elif same_parity:
            dy = abs(three_enter_pt.y() - five_exit_pt.y())
            c1.setX(five_exit_pt.x() + _xScale * dy)
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))
        # case 3: different parity
        else:
            if n5_is_forward:
                c1.setX(five_exit_pt.x() - _xScale *
                        abs(three_enter_pt.y() - five_exit_pt.y()))
            else:
                c1.setX(five_exit_pt.x() + _xScale *
                        abs(three_enter_pt.y() - five_exit_pt.y()))
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))

        # Construct painter path
        painterpath = QPainterPath()
        painterpath.moveTo(five_enter_pt)
        painterpath.lineTo(five_center_pt)
        painterpath.lineTo(five_exit_pt)
        painterpath.quadTo(c1, three_enter_pt)
        painterpath.lineTo(three_center_pt)
        painterpath.lineTo(three_exit_pt)

        self.setPath(painterpath)
        self._updateFloatPen()
示例#27
0
    def _updatePath(self, strand5p):
        """
        Draws a quad curve from the edge of the fromBase
        to the top or bottom of the toBase (q5), and
        finally to the center of the toBase (toBaseEndpoint).

        If floatPos!=None, this is a floatingXover and floatPos is the
        destination point (where the mouse is) while toHelix, toIndex
        are potentially None and represent the base at floatPos.

        """
        group = self.group()
        self.tempReparent()

        node3 = self._node3
        node5 = self._node5

        bw = _BASE_WIDTH

        parent = self.partItem()

        vhi5 = self._virtual_helix_item
        pt5 = vhi5.mapToItem(parent, *node5.point())

        five_is_top = node5.isOnTop()
        five_is_5to3 = node5.isDrawn5to3()

        vhi3 = node3.virtualHelixItem()
        pt3 = vhi3.mapToItem(parent, *node3.point())

        three_is_top = node3.isOnTop()
        three_is_5to3 = node3.isDrawn5to3()
        same_strand = (node5.strandType() == node3.strandType()) and vhi3 == vhi5
        same_parity = five_is_5to3 == three_is_5to3

        # Enter/exit are relative to the direction that the path travels
        # overall.
        five_enter_pt = pt5 + QPointF(0 if five_is_5to3 else 1, 0.5) * bw
        five_center_pt = pt5 + QPointF(0.5, 0.5) * bw
        five_exit_pt = pt5 + QPointF(0.5, 0 if five_is_top else 1) * bw

        three_enter_pt = pt3 + QPointF(0.5, 0 if three_is_top else 1) * bw
        three_center_pt = pt3 + QPointF(0.5, 0.5) * bw
        three_exit_pt = pt3 + QPointF(1 if three_is_5to3 else 0, 0.5) * bw

        c1 = QPointF()
        # case 1: same strand
        if same_strand:
            dx = abs(three_enter_pt.x() - five_exit_pt.x())
            c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x()))
            if five_is_top:
                c1.setY(five_exit_pt.y() - _Y_SCALE * dx)
            else:
                c1.setY(five_exit_pt.y() + _Y_SCALE * dx)
        # case 2: same parity
        elif same_parity:
            dy = abs(three_enter_pt.y() - five_exit_pt.y())
            c1.setX(five_exit_pt.x() + _X_SCALE * dy)
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))
        # case 3: different parity
        else:
            if five_is_top and five_is_5to3:
                c1.setX(five_exit_pt.x() - _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y()))
            else:
                c1.setX(five_exit_pt.x() + _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y()))
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))

        # Construct painter path
        painterpath = QPainterPath()
        painterpath.moveTo(five_enter_pt)
        painterpath.lineTo(five_center_pt)
        painterpath.lineTo(five_exit_pt)

        # The xover5's non-crossing-over end (3') has a connection
        painterpath.quadTo(c1, three_enter_pt)
        painterpath.lineTo(three_center_pt)
        painterpath.lineTo(three_exit_pt)

        tempR = painterpath.boundingRect()
        tempR.adjust(-bw / 2, 0, bw, 0)
        self._click_area.setRect(tempR)
        self.setPath(painterpath)
        node3.updatePositionAndAppearance()
        node5.updatePositionAndAppearance()

        if group:
            group.addToGroup(self)

        self._updateColor(strand5p)
示例#28
0
    def showWedge(self, angle, color,
                  extended=False, rev_gradient=False, outline_only=False):
        """Summary

        Args:
            angle (TYPE): Description
            color (TYPE): Description
            extended (bool, optional): Description
            rev_gradient (bool, optional): Description
            outline_only (bool, optional): Description
        """
        # Hack to keep wedge in front
        # self.setRotation(self.pre_xover_item_group.rotation())

        self._last_params = (angle, color, extended, rev_gradient, outline_only)
        radius = self._radius
        span = self.pre_xover_item_group.partCrossoverSpanAngle() / 2
        radius_adjusted = radius + (_WEDGE_RECT_GAIN / 2)

        tip = QPointF(radius_adjusted, radius_adjusted)
        EXT = 1.35 if extended else 1.0

        # print("wtf", tip, pos)
        base_p2 = QPointF(1, 1)

        line0 = QLineF(tip, QPointF(base_p2))
        line1 = QLineF(tip, QPointF(base_p2))
        line2 = QLineF(tip, QPointF(base_p2))

        quad_scale = 1 + (.22*(span - 5) / 55)  # lo+(hi-lo)*(val-min)/(max-min)
        line0.setLength(radius_adjusted * EXT*quad_scale)  # for quadTo control point
        line1.setLength(radius_adjusted * EXT)
        line2.setLength(radius_adjusted * EXT)
        line0.setAngle(angle)
        line1.setAngle(angle - span)
        line2.setAngle(angle + span)

        path = QPainterPath()

        if outline_only:
            self.setPen(getPenObj(color, 0.5, alpha=128, capstyle=Qt.RoundCap))
            path.moveTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
        else:
            gradient = QRadialGradient(tip, radius_adjusted * EXT)
            color1 = getColorObj(color, alpha=80)
            color2 = getColorObj(color, alpha=0)
            if rev_gradient:
                color1, color2 = color2, color1

            if extended:
                gradient.setColorAt(0, color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT), color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT) + 0.01, color2)
                gradient.setColorAt(1, color2)
            else:
                gradient.setColorAt(0, getColorObj(color, alpha=50))
            brush = QBrush(gradient)
            self.setBrush(brush)

            path.moveTo(line1.p1())
            path.lineTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
            path.lineTo(line2.p1())

        self.setPath(path)
        self.show()
示例#29
0
    def updateFloatPath(self, point=None):
        """
        Draws a quad curve from the edge of the fromBase
        to the top or bottom of the toBase (q5), and
        finally to the center of the toBase (toBaseEndpoint).

        If floatPos!=None, this is a floatingXover and floatPos is the
        destination point (where the mouse is) while toHelix, toIndex
        are potentially None and represent the base at floatPos.

        Args:
            point (None, optional): Description

        """
        node3 = self._node3
        node5 = self._node5

        bw = _BASE_WIDTH

        vhi5 = self._virtual_helix_item
        nucleicacid_part_item = vhi5.partItem()
        pt5 = vhi5.mapToItem(nucleicacid_part_item, *node5.floatPoint())

        n5_is_forward = node5.is_forward

        # Enter/exit are relative to the direction that the path travels
        # overall.
        five_enter_pt = pt5 + QPointF(0 if n5_is_forward else 1, .5)*bw
        five_center_pt = pt5 + QPointF(.5, .5)*bw
        five_exit_pt = pt5 + QPointF(.5, 0 if n5_is_forward else 1)*bw

        vhi3 = node3.virtualHelixItem()

        if point:
            pt3 = point
            n3_is_forward = True
            same_strand = False
            same_parity = False
            three_enter_pt = three_center_pt = three_exit_pt = pt3
        else:
            pt3 = vhi3.mapToItem(nucleicacid_part_item, *node3.point())
            n3_is_forward = node3.is_forward
            same_strand = (n5_is_forward == n3_is_forward) and vhi3 == vhi5
            same_parity = n5_is_forward == n3_is_forward

            three_enter_pt = pt3 + QPointF(.5, 0 if n3_is_forward else 1)*bw
            three_center_pt = pt3 + QPointF(.5, .5)*bw
            three_exit_pt = pt3 + QPointF(1 if n3_is_forward else 0, .5)*bw

        c1 = QPointF()
        # case 1: same strand
        if same_strand:
            dx = abs(three_enter_pt.x() - five_exit_pt.x())
            c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x()))
            if n5_is_forward:
                c1.setY(five_exit_pt.y() - _yScale * dx)
            else:
                c1.setY(five_exit_pt.y() + _yScale * dx)
            # case 2: same parity
        elif same_parity:
            dy = abs(three_enter_pt.y() - five_exit_pt.y())
            c1.setX(five_exit_pt.x() + _xScale * dy)
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))
        # case 3: different parity
        else:
            if n5_is_forward:
                c1.setX(five_exit_pt.x() - _xScale *
                        abs(three_enter_pt.y() - five_exit_pt.y()))
            else:
                c1.setX(five_exit_pt.x() + _xScale *
                        abs(three_enter_pt.y() - five_exit_pt.y()))
            c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y()))

        # Construct painter path
        painterpath = QPainterPath()
        painterpath.moveTo(five_enter_pt)
        painterpath.lineTo(five_center_pt)
        painterpath.lineTo(five_exit_pt)
        painterpath.quadTo(c1, three_enter_pt)
        painterpath.lineTo(three_center_pt)
        painterpath.lineTo(three_exit_pt)

        self.setPath(painterpath)
        self._updateFloatPen()
示例#30
0
    def paintEvent(self, e):
        super().paintEvent(e)
        # 画鼠标位置处的圆
        if 1 in self.parent.painter_tools.values():
            painter = QPainter(self)
            painter.setPen(QPen(self.parent.pencolor, 1, Qt.SolidLine))
            rect = QRectF(self.px - self.parent.tool_width // 2,
                          self.py - self.parent.tool_width // 2,
                          self.parent.tool_width, self.parent.tool_width)
            painter.drawEllipse(rect)
            painter.end()
        if self.startpaint:

            while len(self.parent.eraser_pointlist):  # 画橡皮擦
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                self.pixPainter.setBrush(QColor(0, 0, 0, 0))
                self.pixPainter.setPen(Qt.NoPen)
                self.pixPainter.setCompositionMode(
                    QPainter.CompositionMode_Clear)
                new_pen_point = self.parent.eraser_pointlist.pop(0)
                if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
                    self.pixPainter.drawEllipse(
                        new_pen_point[0] - self.parent.tool_width / 2,
                        new_pen_point[1] - self.parent.tool_width / 2,
                        self.parent.tool_width, self.parent.tool_width)

                self.parent.old_pen = new_pen_point
                self.pixPainter.end()

            while len(self.parent.pen_pointlist):  # 画笔功能
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                self.pixPainter.setBrush(self.parent.pencolor)
                self.pixPainter.setPen(
                    QPen(self.parent.pencolor, self.parent.tool_width,
                         Qt.SolidLine))
                new_pen_point = self.parent.pen_pointlist.pop(0)
                if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
                    path = QPainterPath(
                        QPoint(self.parent.old_pen[0], self.parent.old_pen[1]))
                    path.quadTo(
                        QPoint(
                            (new_pen_point[0] + self.parent.old_pen[0]) / 2,
                            (new_pen_point[1] + self.parent.old_pen[1]) / 2),
                        QPoint(new_pen_point[0], new_pen_point[1]))
                    self.pixPainter.drawPath(path)
                self.parent.old_pen = new_pen_point
                self.pixPainter.end()

            while len(self.parent.drawpix_pointlist):  # 画马赛克/材质贴图功能
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                brush = QBrush(self.parent.pencolor)
                brush.setTexture(QPixmap(self.pixpng))
                self.pixPainter.setBrush(brush)
                self.pixPainter.setPen(Qt.NoPen)
                new_pen_point = self.parent.drawpix_pointlist.pop(0)
                if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
                    self.pixPainter.drawEllipse(
                        new_pen_point[0] - self.parent.tool_width / 2,
                        new_pen_point[1] - self.parent.tool_width / 2,
                        self.parent.tool_width, self.parent.tool_width)

                self.parent.old_pen = new_pen_point
                self.pixPainter.end()

            if self.parent.drawrect_pointlist[0][
                    0] != -2 and self.parent.drawrect_pointlist[1][
                        0] != -2:  # 画方形
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                temppainter = QPainter(self)
                temppainter.setPen(QPen(self.parent.pencolor, 3, Qt.SolidLine))

                poitlist = self.parent.drawrect_pointlist
                temppainter.drawRect(min(poitlist[0][0], poitlist[1][0]),
                                     min(poitlist[0][1], poitlist[1][1]),
                                     abs(poitlist[0][0] - poitlist[1][0]),
                                     abs(poitlist[0][1] - poitlist[1][1]))
                temppainter.end()
                if self.parent.drawrect_pointlist[2] == 1:
                    self.pixPainter.setPen(
                        QPen(self.parent.pencolor, 3, Qt.SolidLine))
                    self.pixPainter.drawRect(
                        min(poitlist[0][0], poitlist[1][0]),
                        min(poitlist[0][1], poitlist[1][1]),
                        abs(poitlist[0][0] - poitlist[1][0]),
                        abs(poitlist[0][1] - poitlist[1][1]))

                    self.parent.drawrect_pointlist = [[-2, -2], [-2, -2], 0]
                self.pixPainter.end()

            if self.parent.drawcircle_pointlist[0][
                    0] != -2 and self.parent.drawcircle_pointlist[1][
                        0] != -2:  # 画圆
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                temppainter = QPainter(self)
                temppainter.setPen(QPen(self.parent.pencolor, 3, Qt.SolidLine))
                poitlist = self.parent.drawcircle_pointlist
                temppainter.drawEllipse(min(poitlist[0][0], poitlist[1][0]),
                                        min(poitlist[0][1], poitlist[1][1]),
                                        abs(poitlist[0][0] - poitlist[1][0]),
                                        abs(poitlist[0][1] - poitlist[1][1]))
                temppainter.end()
                if self.parent.drawcircle_pointlist[2] == 1:
                    self.pixPainter.setPen(
                        QPen(self.parent.pencolor, 3, Qt.SolidLine))
                    self.pixPainter.drawEllipse(
                        min(poitlist[0][0], poitlist[1][0]),
                        min(poitlist[0][1], poitlist[1][1]),
                        abs(poitlist[0][0] - poitlist[1][0]),
                        abs(poitlist[0][1] - poitlist[1][1]))
                    self.parent.drawcircle_pointlist = [[-2, -2], [-2, -2], 0]
                self.pixPainter.end()

            if self.parent.drawarrow_pointlist[0][
                    0] != -2 and self.parent.drawarrow_pointlist[1][
                        0] != -2:  # 画箭头
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                temppainter = QPainter(self)

                poitlist = self.parent.drawarrow_pointlist
                temppainter.translate(poitlist[0][0], poitlist[0][1])
                degree = math.degrees(
                    math.atan2(poitlist[1][1] - poitlist[0][1],
                               poitlist[1][0] - poitlist[0][0]))
                temppainter.rotate(degree)
                dx = math.sqrt((poitlist[1][1] - poitlist[0][1])**2 +
                               (poitlist[1][0] - poitlist[0][0])**2)
                dy = 30
                temppainter.drawPixmap(0, -dy / 2,
                                       QPixmap(':/arrow.png').scaled(dx, dy))

                temppainter.end()
                if self.parent.drawarrow_pointlist[2] == 1:
                    self.pixPainter.translate(poitlist[0][0], poitlist[0][1])
                    degree = math.degrees(
                        math.atan2(poitlist[1][1] - poitlist[0][1],
                                   poitlist[1][0] - poitlist[0][0]))
                    self.pixPainter.rotate(degree)
                    dx = math.sqrt((poitlist[1][1] - poitlist[0][1])**2 +
                                   (poitlist[1][0] - poitlist[0][0])**2)
                    dy = 30
                    self.pixPainter.drawPixmap(
                        0, -dy / 2,
                        QPixmap(':/arrow.png').scaled(dx, dy))
                    self.parent.drawarrow_pointlist = [[-2, -2], [-2, -2], 0]
                    # self.parent.drawarrow_pointlist[0] = [-2, -2]
                self.pixPainter.end()

            if len(self.parent.drawtext_pointlist
                   ) > 1 or self.parent.text_box.paint:  # 画文字
                self.pixPainter = QPainter(self.pixmap())
                self.pixPainter.setRenderHint(QPainter.Antialiasing)
                self.parent.text_box.paint = False
                # print(self.parent.drawtext_pointlist)
                text = self.parent.text_box.toPlainText()
                self.parent.text_box.clear()
                pos = self.parent.drawtext_pointlist.pop(0)
                if text:
                    self.pixPainter.setFont(
                        QFont('微软雅黑', self.parent.tool_width))
                    self.pixPainter.setPen(
                        QPen(self.parent.pencolor, 3, Qt.SolidLine))
                    self.pixPainter.drawText(
                        pos[0] +
                        self.parent.text_box.document.size().height() / 8,
                        pos[1] +
                        self.parent.text_box.document.size().height() * 32 /
                        41, text)

                self.pixPainter.end()
        else:
            self.startpaint = 1
示例#31
0
    def drawOutline(self, painter):

        path = QPainterPath()

        path.moveTo(-7.5, 257)
        path.quadTo(-12.5, 263, -12.5, 267.5)
        path.quadTo(-12.5, 278, 0, 280)
        path.quadTo(12.5, 278, 12.5, 267.5)
        path.moveTo(12.5, 267.5)
        path.quadTo(12.5, 263, 7.5, 257)

        path.lineTo(7.5, 25)
        path.quadTo(7.5, 12.5, 0, 12.5)
        path.quadTo(-7.5, 12.5, -7.5, 25)
        path.lineTo(-7.5, 257)

        p1 = QPointF(-2.0, 0)
        p2 = QPointF(12.5, 0)

        linearGrad = QLinearGradient(p1, p2)
        linearGrad.setSpread(QGradient.ReflectSpread)
        linearGrad.setColorAt(1, QColor(0, 150, 255, 170))
        linearGrad.setColorAt(0, QColor(255, 255, 255, 0))

        painter.setBrush(QBrush(linearGrad))
        painter.setPen(Qt.black)
        painter.drawPath(path)

        pen = QPen()
        length = 12

        for i in range(33):

            pen.setWidthF(1.0)
            length = 12

            if i % 4:
                length = 8
                pen.setWidthF(0.8)

            if i % 2:
                length = 5
                pen.setWidthF(0.6)

            painter.setPen(pen)
            painter.drawLine(-7, 28 + i * 7, -7 + length, 28 + i * 7)

        for i in range(9):

            num = self.m_min + i * (self.m_max - self.m_min) / 8
            val = "{0}".format(num)
            fm = painter.fontMetrics()
            size = fm.size(Qt.TextSingleLine, val)
            point = QPointF(OFFSET, 252 - i * 28 + size.width() / 4.0)
            painter.drawText(point, val)
示例#32
0
	def endShape(self, mode, vertices, isCurve, isBezier, isQuadratic, isContour, shapeKind):
		if len(vertices) == 0:
			return 
		closeShape = mode == CLOSE

		if closeShape and not isContour:
			vertices.append(vertices[0])

		if isCurve and (shapeKind == POLYGON or shapeKind == None):
			s = 1 - self.curveTightness
			path = QPainterPath()
			path.moveTo(vertices[1][0], vertices[1][1])

			for i in range(1, len(vertices) - 2):
				v = vertices[i]
				b = []
				b.append([v[0], v[1]])
				b.append([
					v[0] + (s * vertices[i + 1][0] - s * vertices[i - 1][0]) / 6,
					v[1] + (s * vertices[i + 1][1] - s * vertices[i - 1][1]) / 6
				])
				b.append([
					vertices[i + 1][0] +
						(s * vertices[i][0] - s * vertices[i + 2][0]) / 6,
					vertices[i + 1][1] + (s * vertices[i][1] - s * vertices[i + 2][1]) / 6
				])
				b.append([vertices[i + 1][0], vertices[i + 1][1]])
				path.cubicTo(
					b[1][0],
					b[1][1],
					b[2][0],
					b[2][1],
					b[3][0],
					b[3][1]
				)

			if closeShape:
				path.lineTo(vertices[i + 1][0], vertices[i + 1][1])
			self.renderPath(path)

		elif isBezier and (shapeKind == POLYGON or shapeKind == None):
			path = QPainterPath()
			path.moveTo(vertices[0][0], vertices[0][1])

			for v in vertices:
				if len(v) == 2:
					path.lineTo(v[0], v[1])
				else:
					path.cubicTo(
						v[0],
						v[1],
						v[2],
						v[3],
						v[4],
						v[5],
					)
			self.renderPath(path)

		elif isQuadratic and (shapeKind == POLYGON or shapeKind == None):
			path = QPainterPath()
			path.moveTo(vertices[0][0], vertices[0][1])
			for v in vertices:
				if len(v) == 2:
					path.lineTo(v[0], v[1])
				else:
					path.quadTo(
						v[0],
						v[1],
						v[2],
						v[3],
					)
			self.renderPath(path)

		else:
			if shapeKind == POINTS:
				for p in vertices:
					self.point(p[0], p[1])
			elif shapeKind == LINES:
				for i in range(0, len(vertices) - 1, 2):
					self.line(vertices[i][0], vertices[i][1], vertices[i + 1][0], vertices[i + 1][1])
			elif shapeKind == TRIANGLES:
				for i in range(0, len(vertices) - 2, 3):
					self.triangle(vertices[i][0], vertices[i][1], 
						vertices[i + 1][0], vertices[i + 1][1],
						vertices[i + 2][0], vertices[i + 2][1])
			elif shapeKind == TRIANGLE_STRIP:
				for i in range(len(vertices) - 2):
					self.triangle(vertices[i][0], vertices[i][1], 
						vertices[i + 1][0], vertices[i + 1][1],
						vertices[i + 2][0], vertices[i + 2][1])
			elif shapeKind == TRIANGLE_FAN:
				for i in range(1, len(vertices) - 1):
					self.triangle(vertices[0][0], vertices[0][1], 
							vertices[i][0], vertices[i][1],
							vertices[i + 1][0], vertices[i + 1][1])
			elif shapeKind == QUADS:
				for i in range(0, len(vertices) - 3, 4):
					self.quad(vertices[i][0], vertices[i][1], 
							vertices[i + 1][0], vertices[i + 1][1],
							vertices[i + 2][0], vertices[i + 2][1],
							vertices[i + 3][0], vertices[i + 3][1])
			elif shapeKind == QUAD_STRIP:
				for i in range(0, len(vertices) - 3, 2):
					self.quad(vertices[i][0], vertices[i][1], 
							vertices[i + 1][0], vertices[i + 1][1],
							vertices[i + 2][0], vertices[i + 2][1],
							vertices[i + 3][0], vertices[i + 3][1])
			else:
				path = QPainterPath()
				path.moveTo(vertices[0][0], vertices[0][1])
				for p in vertices:
					path.lineTo(p[0], p[1])
				self.renderPath(path)

		return
示例#33
0
 def drawEdge(self, x1, y1, x2, y2, index, curve, tear=False):
     """
     Draw an edge from x1, y1 to x2, y2.  Edges connect two nodes
     --Args--
     index: the edge index
     curve: distance from center of straight edge to a point on
            curved edge (can be positive or negitive.  Used to
            keep edges from overlapping.
     tear: if true draw in tear edge style
     """
     # determine if edge conntects a node to itself.
     if abs(x1 - x2) < 0.01 and abs(y1 - y2) < 0.01:
         path = QPainterPath()
         curve = curve * 2
         path.addEllipse(x1, y1 - curve / 2.0, curve, curve)
         if tear:
             gi = self.addPath(path, self.edgePen)
         else:
             gi = self.addPath(path, self.tearEdgePen)
     else:
         # mid point of the edge if it is a straight line
         xmid = (x1 + x2) / 2.0
         ymid = (y1 + y2) / 2.0
         # get the angle of the edge and the angle perpendicular
         ang = math.atan2((y2 - y1), (x2 - x1))
         ang_perp = math.atan2((x1 - x2), (y2 - y1))
         # calculate the mid point of the curved edge
         xcurve = xmid + curve * math.cos(ang_perp)
         ycurve = ymid + curve * math.sin(ang_perp)
         # calculate control point for drawing quaratic curve
         xcontrol = 2 * xcurve - xmid
         ycontrol = 2 * ycurve - ymid
         # draw Edge
         path = QPainterPath()
         path.moveTo(x1, y1)
         path.quadTo(xcontrol, ycontrol, x2, y2)
         p2 = QPainterPathStroker()
         path = p2.createStroke(path)
         # if edge is selected draw it highlighted
         if index in self.selectedEdges:
             self.addPath(path, self.eSelectionPen)
         # if edge is a tear draw it tear style else draw it normal
         if tear:
             gi = self.addPath(path, self.tearEdgePen)
         else:
             gi = self.addPath(path, self.edgePen)
         # Add data to edge so if seleted we can determine that it
         # is an edge and which edge it is.
         gi.setData(1, index)
         gi.setData(2, "edge")
         # Draw the arrow
         path = QPainterPath()
         xs = xcurve + self.edgeArrowSize * math.cos(ang)
         ys = ycurve + self.edgeArrowSize * math.sin(ang)
         path.moveTo(xs, ys)
         path.lineTo(
             xs
             - self.edgeArrowSize * math.cos(ang)
             + self.edgeArrowSize / 2.0 * math.cos(ang_perp),
             ys
             - self.edgeArrowSize * math.sin(ang)
             + self.edgeArrowSize / 2.0 * math.sin(ang_perp),
         )
         path.lineTo(
             xs
             - self.edgeArrowSize * math.cos(ang)
             - self.edgeArrowSize / 2.0 * math.cos(ang_perp),
             ys
             - self.edgeArrowSize * math.sin(ang)
             - self.edgeArrowSize / 2.0 * math.sin(ang_perp),
         )
         path.lineTo(xs, ys)
         gi = self.addPath(path, self.edgePen, self.edgeArrowBrush)
         # Add data so selecting the arrow in like selecting the edge
         gi.setData(1, index)
         gi.setData(2, "edge")
示例#34
0
    def showWedge(self,
                  angle,
                  color,
                  extended=False,
                  rev_gradient=False,
                  outline_only=False):
        """Summary

        Args:
            angle (TYPE): Description
            color (TYPE): Description
            extended (bool, optional): Description
            rev_gradient (bool, optional): Description
            outline_only (bool, optional): Description
        """
        # Hack to keep wedge in front
        # self.setRotation(self.pre_xover_item_group.rotation())

        self._last_params = (angle, color, extended, rev_gradient,
                             outline_only)
        radius = self._radius
        span = self.pre_xover_item_group.partCrossoverSpanAngle() / 2
        radius_adjusted = radius + (_WEDGE_RECT_GAIN / 2)

        tip = QPointF(radius_adjusted, radius_adjusted)
        EXT = 1.35 if extended else 1.0

        # print("wtf", tip, pos)
        base_p2 = QPointF(1, 1)

        line0 = QLineF(tip, QPointF(base_p2))
        line1 = QLineF(tip, QPointF(base_p2))
        line2 = QLineF(tip, QPointF(base_p2))

        quad_scale = 1 + (.22 *
                          (span - 5) / 55)  # lo+(hi-lo)*(val-min)/(max-min)
        line0.setLength(radius_adjusted * EXT *
                        quad_scale)  # for quadTo control point
        line1.setLength(radius_adjusted * EXT)
        line2.setLength(radius_adjusted * EXT)
        line0.setAngle(angle)
        line1.setAngle(angle - span)
        line2.setAngle(angle + span)

        path = QPainterPath()

        if outline_only:
            self.setPen(getPenObj(color, 0.5, alpha=128, capstyle=Qt.RoundCap))
            path.moveTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
        else:
            gradient = QRadialGradient(tip, radius_adjusted * EXT)
            color1 = getColorObj(color, alpha=80)
            color2 = getColorObj(color, alpha=0)
            if rev_gradient:
                color1, color2 = color2, color1

            if extended:
                gradient.setColorAt(0, color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT),
                                    color1)
                gradient.setColorAt(
                    radius_adjusted / (radius_adjusted * EXT) + 0.01, color2)
                gradient.setColorAt(1, color2)
            else:
                gradient.setColorAt(0, getColorObj(color, alpha=50))
            brush = QBrush(gradient)
            self.setBrush(brush)

            path.moveTo(line1.p1())
            path.lineTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
            path.lineTo(line2.p1())

        self.setPath(path)
        self.show()
示例#35
0
    def generatePath(self, outerRimPoints, innerRimPoints):
        # MoveTo, LineTo, QuadTo
        orp = outerRimPoints
        irp = innerRimPoints

        # For debugging purposes:
        #print("Outer: " + str(orp))
        #print("Inner: " + str(irp))

        p = QPainterPath()
        # Set to starting position: top center
        p.moveTo(orp['topCenter'])

        # Generate outer rim path
        p.lineTo(orp['topRight']['topSidePoint'])
        p.quadTo(orp['topRight']['controlPoint'], orp['topRight']['rightSidePoint'])
        p.lineTo(orp['bottomRight']['rightSidePoint'])
        p.quadTo(orp['bottomRight']['controlPoint'], orp['bottomRight']['bottomSidePoint'])
        p.lineTo(orp['bottomLeft']['bottomSidePoint'])
        p.quadTo(orp['bottomLeft']['controlPoint'], orp['bottomLeft']['leftSidePoint'])
        p.lineTo(orp['topLeft']['leftSidePoint'])
        p.quadTo(orp['topLeft']['controlPoint'], orp['topLeft']['topSidePoint'])
        p.lineTo(orp['topCenter'])

        # Connect to inner rim path
        p.lineTo(irp['topCenter'])

        # Generate inner rim path
        p.lineTo(irp['topLeft']['topSidePoint'])
        p.quadTo(irp['topLeft']['controlPoint'], irp['topLeft']['leftSidePoint'])
        p.lineTo(irp['bottomLeft']['leftSidePoint'])
        p.quadTo(irp['bottomLeft']['controlPoint'], irp['bottomLeft']['bottomSidePoint'])
        p.lineTo(irp['bottomRight']['bottomSidePoint'])
        p.quadTo(irp['bottomRight']['controlPoint'], irp['bottomRight']['rightSidePoint'])
        p.lineTo(irp['topRight']['rightSidePoint'])
        p.quadTo(irp['topRight']['controlPoint'], irp['topRight']['topSidePoint'])
        p.lineTo(irp['topCenter'])

        # Path 'should' be closed automatically, if not here is one final lineTo:
        # p.lineTo(orp['topCenter'])

        return p