예제 #1
0
    def setWedgeGizmo(self, neighbor_virtual_helix: int,
                      neighbor_virtual_helix_item: SliceVirtualHelixItemT):
        """Adds a :class:`WedgeGizmo` to oriented toward the specified neighbor vhi.

        Called by :meth:`SliceNucleicAcidPartItem._refreshVirtualHelixItemGizmos`,
        before :meth:`setWedgeGizmo` and :meth:`endAddWedgeGizmos`.

        Args:
            neighbor_virtual_helix: the id_num of neighboring virtual helix
            neighbor_virtual_helix_item: the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item
        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS * 1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
예제 #2
0
    def setWedgeGizmo(self, neighbor_virtual_helix,
                      neighbor_virtual_helix_item):
        """Adds a WedgeGizmo to oriented toward the specified neighbor vhi.

        Called by NucleicAcidPartItem _refreshVirtualHelixItemGizmos, in between
        with beginAddWedgeGizmos and endAddWedgeGizmos.

        Args:
            neighbor_virtual_helix (int): the id_num of neighboring virtual helix
            neighbor_virtual_helix_item (cadnano.views.sliceview.virtualhelixitem.VirtualHelixItem):
            the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item

        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS * 1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
예제 #3
0
    def setWedgeGizmo(self, neighbor_virtual_helix: int,
                            neighbor_virtual_helix_item: GridVirtualHelixItemT):
        """Adds a WedgeGizmo to oriented toward the specified neighbor vhi.

        Called by NucleicAcidPartItem _refreshVirtualHelixItemGizmos, in between
        with beginAddWedgeGizmos and endAddWedgeGizmos.

        Args:
            neighbor_virtual_helix: the id_num of neighboring virtual helix
            neighbor_virtual_helix_item:
            the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item

        nvhi_name = nvhi.getProperty('name')
        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS*1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
            nvhi_name = nvhi_name + '*'  # mark as invalid
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
예제 #4
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(
                onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
예제 #5
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(onCurve.x, onCurve.y, otherPoint.x,
                               otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
예제 #6
0
    def _draw_arrow(self, event, painter):
        if self.info["mouth_is_opened"][0] == False or self.prediction == 4:
            return

        angles = [135, 90, 45, 180, None, 0, 225, 270, 0]
        angleline = QLineF()
        angleline.setP1(QPointF(*_mouse_controller.position))
        angleline.setAngle(angles[self.prediction])
        angleline.setLength(100)
        painter.setPen(QPen(Qt.red, 5, Qt.SolidLine))
        painter.drawLine(angleline)
예제 #7
0
def rotateUIPointAroundRefLine(x1, y1, x2, y2, pt):
    """
    Given three points p1, p2, pt this rotates pt around p2 such that p1,p2 and
    p1,pt are collinear.
    """
    line = QLineF(pt.x, pt.y, x2, y2)
    p2p_l = line.length()
    line.setP1(QPointF(x1, y1))
    p1p2_l = line.length()
    if not p1p2_l:
        return
    line.setLength(p1p2_l + p2p_l)
    pt.x = line.x2()
    pt.y = line.y2()
예제 #8
0
def rotateUIPointAroundRefLine(x1, y1, x2, y2, pt):
    """
    Given three points p1, p2, pt this rotates pt around p2 such that p1,p2 and
    p1,pt are collinear.
    """
    line = QLineF(pt.x, pt.y, x2, y2)
    p2p_l = line.length()
    line.setP1(QPointF(x1, y1))
    p1p2_l = line.length()
    if not p1p2_l:
        return
    line.setLength(p1p2_l + p2p_l)
    pt.x = line.x2()
    pt.y = line.y2()
예제 #9
0
class MyArrow(QGraphicsLineItem):
    def __init__(self, scene, Source, Dest):
        super(MyArrow, self).__init__()
        #设置起点x,y
        Source_x = Source[0]
        Source_y = Source[1]
        #设置终点x,y
        Dest_x = Dest[0]
        Dest_y = Dest[1]
        #绘制连线
        self.source = QPointF(Source_x, Source_y)
        self.dest = QPointF(Dest_x, Dest_y)
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 20)
        scene.addItem(self)

    def prepareGeometryChange(self):
        self.update()

    def paint(self, QPainter, QStyleOptionGraphicsItem, QWidget_widget=None):

        # setPen
        pen = QPen()
        pen.setWidth(2)
        pen.setJoinStyle(Qt.MiterJoin)
        QPainter.setPen(pen)

        # setBrush
        brush = QBrush()
        brush.setColor(Qt.black)
        brush.setStyle(Qt.SolidPattern)
        QPainter.setBrush(brush)

        #绘制终点箭头
        v = self.line.unitVector()
        v.setLength(10)
        v.translate(QPointF(self.line.dx(), self.line.dy()))

        n = v.normalVector()
        n.setLength(n.length() * 0.5)
        n2 = n.normalVector().normalVector()

        p1 = v.p2()
        p2 = n.p2()
        p3 = n2.p2()

        QPainter.drawLine(self.line)
        QPainter.drawPolygon(p1, p2, p3)
예제 #10
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        siblings = _getOffCurveSiblingPoints(contour, point)
        # if an onCurve is selected, the offCurve will move along with it
        if not siblings:
            return
        point.move(delta)
        for onCurve, otherPoint in siblings:
            if not onCurve.smooth:
                continue
            # if the onCurve is smooth, we need to either...
            if otherPoint.segmentType is None and not otherPoint.selected:
                # keep the other offCurve inline
                line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
                otherLine = QLineF(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
                line.setLength(line.length() + otherLine.length())
                otherPoint.x = line.x2()
                otherPoint.y = line.y2()
            else:
                # keep point in tangency with onCurve -> otherPoint segment,
                # i.e. do an orthogonal projection
                point.x, point.y, _ = bezierMath.lineProjection(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y,
                    point.x, point.y, False)
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                # avoid double move for qCurve with single offCurve
                if d > 0:
                    otherPt = contour.getPoint(index + 2 * d)
                    if otherPt.segmentType is not None and \
                            otherPt.segmentType != "move" and otherPt.selected:
                        continue
                pt.move(delta)
                maybeProjectUISmoothPointOffcurve(contour, point)
    contour.dirty = True
예제 #11
0
    def ulti(self):
        scene_items = self.scene().items()

        for i in scene_items:
            if (isinstance(i, Minion) or isinstance(i, BigMinion)) and i.team != self.team:
                this_line = QLineF(self.pos(), i.pos())
                if this_line.length() <= 150:
                    this_line.setLength(150)
                    i.setPos(i.x() + this_line.dx(), i.y() + this_line.dy())
            elif (i.__class__.__name__ == 'Tower' or i.__class__.__name__ == 'Nexus' or
                    i.__class__.__name__ == 'Inhibitor') and i.team != self.team:
                this_line = QLineF(self.pos(), i.pos())
                if this_line.length() <= 150:
                    i.decrease_health(100)

        self.ulti_available = False
        self.ulti_cooldown_timer.start(self.cooldown)
예제 #12
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
예제 #13
0
	def drawWidget(self, qp):
		c = self.rect().center()
		c_coords = c.x(), c.y()
		background_color = self.palette().color(QPalette.Background)

		# paint inner trackpad
		qp.setPen(QPen(self.fishbowl_color, self.fishbowl_border_size, Qt.SolidLine))
		# draw fishbowl
		qp.setBrush(QBrush(Qt.gray, Qt.SolidPattern))
		qp.drawEllipse(c, *([self.fishbowl_size] * 2))

		# draw axis lines
		qp.setPen(QPen(self.fishbowl_color, self.fishbowl_thin_border_size, Qt.DashDotDotLine))
		for angle in range(0, 420, 45):
			line = QLineF(); line.setP1(c); line.setAngle(angle); line.setLength(self.fishbowl_size)
			qp.drawLine(line)
		# draw wheel separators
		line = QLineF(); line.setP1(c + QPoint(self.wheel_size, 0)); line.setAngle(0); line.setLength(self.wheel_width)
		qp.drawLine(line)
		line = QLineF(); line.setP1(c + QPoint(0, -self.wheel_size)); line.setAngle(90); line.setLength(self.wheel_width)
		qp.drawLine(line)
		line = QLineF(); line.setP1(c + QPoint(-self.wheel_size, 0)); line.setAngle(180); line.setLength(self.wheel_width)
		qp.drawLine(line)
		line = QLineF(); line.setP1(c + QPoint(0, self.wheel_size)); line.setAngle(270); line.setLength(self.wheel_width)
		qp.drawLine(line)

		qp.setPen(QPen(self.fishbowl_color, self.fishbowl_border_size, Qt.SolidLine))

		# draw dead enemies
		for i, enemy in enumerate([x for x in self.enemies if x.dead]):
			qp.setBrush(QBrush(enemy.color, Qt.SolidPattern))
			qp.drawEllipse(c + QPoint(*self.scale_point(enemy.coords)), *([self.npc_size] * 2))
		# draw alive enemies
		for i, enemy in enumerate([x for x in self.enemies if not x.dead]):
			qp.setBrush(QBrush(enemy.color, Qt.SolidPattern))
			qp.drawEllipse(c + QPoint(*self.scale_point(enemy.coords)), *([self.npc_size] * 2))

		# draw player
		qp.setBrush(QBrush(self.player.color, Qt.SolidPattern))
		qp.drawEllipse(c + QPoint(*self.scale_point(self.player.coords)), *([self.npc_size] * 2))
예제 #14
0
    def __init__(self, position, angle, arrow_size, value, unit):
        super(StressRepresentation, self).__init__()
        arrow_line = QLineF()
        arrow_line.setP1(position)
        arrow_line.setLength(arrow_size)
        arrow_line.setAngle(angle)
        arrow = QGraphicsLineItem()
        arrow.setLine(arrow_line)
        self.addToGroup(arrow)

        arrow_head1_line = QLineF()
        arrow_head1_line.setP1(arrow_line.p1())
        arrow_head1_line.setLength(arrow_size / 4)
        arrow_head1_line.setAngle(arrow_line.angle() + 45)
        arrow_head1 = QGraphicsLineItem()
        arrow_head1.setLine(arrow_head1_line)
        self.addToGroup(arrow_head1)

        arrow_head2_line = QLineF()
        arrow_head2_line.setP1(arrow_line.p1())
        arrow_head2_line.setLength(arrow_size / 4)
        arrow_head2_line.setAngle(arrow_line.angle() - 45)
        arrow_head2 = QGraphicsLineItem()
        arrow_head2.setLine(arrow_head2_line)
        self.addToGroup(arrow_head2)

        text = QGraphicsTextItem()
        text.setPlainText(f'{str(value)}{unit}')
        text.setPos(arrow_line.p2())
        self.addToGroup(text)

        self._set_color()
예제 #15
0
    def move_forward(self):
        # move object
        if self.should_be_moving:
            ln = QLineF(self.pos(), self.destination)
            ln.setLength(self.speed)

            self.rotate_to_point(self.destination)

            # avoid collision
            colliding_items = self.collidingItems()
            for i in colliding_items:
                if isinstance(i, StaticGameObject):
                    collision_line = QLineF(self.pos(), i.pos())
                    collision_line.setLength(30)
                    self.setPos(self.x() - collision_line.dx(),
                                self.y() - collision_line.dy())

            # move object forward at current angle
            self.setPos(self.x() + ln.dx(), self.y() + ln.dy())

        self.x_prev = self.pos().x()
        self.y_prev = self.pos().y()
예제 #16
0
    def move_forward(self):
        '''Overwriting move forward so it does not evade obstacles '''
        # move object
        if self.has_target:
            return

        if self.should_be_moving:
            ln = QLineF(self.pos(), self.destination)
            ln.setLength(self.speed)

            self.rotate_to_point(self.destination)

            # avoid collision
            colliding_items = self.collidingItems()
            for i in colliding_items:
                if isinstance(i, StaticGameObject):
                    return

            # move object forward at current angle
            self.setPos(self.x() + ln.dx(), self.y() + ln.dy())

        self.x_prev = self.pos().x()
        self.y_prev = self.pos().y()
예제 #17
0
def arrow_path_plain(line, width):
    """
    Return an :class:`QPainterPath` of a plain 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))
    path.moveTo(baseline.p1())
    path.lineTo(baseline.p2())

    stroker = QPainterPathStroker()
    stroker.setWidth(width)
    path = stroker.createStroke(path)

    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(),
        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
예제 #18
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()
예제 #19
0
파일: drawing.py 프로젝트: sahwar/trufont
def _drawGuidelines(painter,
                    glyph,
                    scale,
                    rect,
                    guidelines,
                    drawLines=True,
                    drawText=True,
                    drawSelection=True,
                    color=None):
    if not (drawLines or drawText):
        return
    xMin, yMin, width, height = rect
    xMax = xMin + width
    yMax = yMin + height
    for line in guidelines:
        color_ = color
        if color_ is None:
            if line.color:
                color_ = colorToQColor(line.color)
            else:
                color_ = defaultColor("glyphGuideline")
        painter.save()
        painter.setPen(color)
        line1 = None
        if None not in (line.x, line.y):
            if line.angle is not None:
                # make an infinite line that intersects *(line.x, line.y)*
                # 1. make horizontal line from *(line.x, line.y)* of length
                # *diagonal*
                diagonal = math.sqrt(width**2 + height**2)
                line1 = QLineF(line.x, line.y, line.x + diagonal, line.y)
                # 2. set the angle
                # defcon guidelines are clockwise
                line1.setAngle(line.angle)
                # 3. reverse the line and set length to 2 * *diagonal*
                line1.setPoints(line1.p2(), line1.p1())
                line1.setLength(2 * diagonal)
            else:
                line1 = QLineF(xMin, line.y, xMax, line.y)
        textX = 0
        textY = 0
        if drawLines:
            if line1 is not None:
                # line
                drawLine(painter, line1.x1(), line1.y1(), line1.x2(),
                         line1.y2())
                # point
                x, y = line.x, line.y
                smoothWidth = 8 * scale
                smoothHalf = smoothWidth / 2.0
                painter.save()
                pointPath = QPainterPath()
                x -= smoothHalf
                y -= smoothHalf
                pointPath.addEllipse(x, y, smoothWidth, smoothWidth)
                pen = QPen(color_)
                pen.setWidthF(1 * scale)
                painter.setPen(pen)
                if drawSelection and line.selected:
                    painter.fillPath(pointPath, color_)
                painter.drawPath(pointPath)
                painter.restore()
            else:
                if line.y is not None:
                    drawLine(painter, xMin, line.y, xMax, line.y)
                elif line.x is not None:
                    drawLine(painter, line.x, yMin, line.x, yMax)
        if drawText and line.name:
            if line1 is not None:
                textX = line.x
                textY = line.y - 6 * scale
                xAlign = "center"
            else:
                if line.y is not None:
                    fontSize = painter.font().pointSize()
                    textX = glyph.width + 6 * scale
                    textY = line.y - (fontSize / 3.5) * scale
                elif line.x is not None:
                    textX = line.x + 6 * scale
                    textY = 0
                xAlign = "left"
            drawTextAtPoint(painter,
                            line.name,
                            textX,
                            textY,
                            scale,
                            xAlign=xAlign)
        painter.restore()
예제 #20
0
def _drawGuidelines(painter, glyph, scale, rect, guidelines, drawLines=True,
                    drawText=True, drawSelection=True, color=None):
    if not (drawLines or drawText):
        return
    xMin, yMin, width, height = rect
    xMax = xMin + width
    yMax = yMin + height
    fontSize = painter.font().pointSize()
    for line in guidelines:
        color_ = color
        if color_ is None:
            if line.color:
                color_ = colorToQColor(line.color)
            else:
                color_ = defaultColor("glyphGuideline")
        painter.save()
        painter.setPen(color)
        line1 = None
        if None not in (line.x, line.y):
            if line.angle is not None:
                # make an infinite line that intersects *(line.x, line.y)*
                # 1. make horizontal line from *(line.x, line.y)* of length
                # *diagonal*
                diagonal = math.sqrt(width**2 + height**2)
                line1 = QLineF(line.x, line.y, line.x + diagonal, line.y)
                # 2. set the angle
                # defcon guidelines are clockwise
                line1.setAngle(line.angle)
                # 3. reverse the line and set length to 2 * *diagonal*
                line1.setPoints(line1.p2(), line1.p1())
                line1.setLength(2 * diagonal)
            else:
                line1 = QLineF(xMin, line.y, xMax, line.y)
        textX = 0
        textY = 0
        if drawLines:
            if line1 is not None:
                # line
                drawLine(
                    painter, line1.x1(), line1.y1(), line1.x2(), line1.y2())
                # point
                x, y = line.x, line.y
                smoothWidth = 8 * scale
                smoothHalf = smoothWidth / 2.0
                painter.save()
                pointPath = QPainterPath()
                x -= smoothHalf
                y -= smoothHalf
                pointPath.addEllipse(x, y, smoothWidth, smoothWidth)
                pen = QPen(color_)
                pen.setWidthF(1 * scale)
                painter.setPen(pen)
                if drawSelection and line.selected:
                    painter.fillPath(pointPath, color_)
                painter.drawPath(pointPath)
                painter.restore()
            else:
                if line.y is not None:
                    drawLine(painter, xMin, line.y, xMax, line.y)
                elif line.x is not None:
                    drawLine(painter, line.x, yMin, line.x, yMax)
        if drawText and line.name:
            if line1 is not None:
                textX = line.x
                textY = line.y - 6 * scale
                xAlign = "center"
            else:
                if line.y is not None:
                    textX = glyph.width + 6 * scale
                    textY = line.y - (fontSize / 3.5) * scale
                elif line.x is not None:
                    textX = line.x + 6 * scale
                    textY = 0
                xAlign = "left"
            drawTextAtPoint(
                painter, line.name, textX, textY, scale, xAlign=xAlign)
        painter.restore()
예제 #21
0
class LineItem(QGraphicsLineItem):
    def __init__(self,
                 boxName,
                 fromBox,
                 toBox,
                 position,
                 scene,
                 parentForm,
                 style=Qt.SolidLine,
                 rect=None,
                 matrix=QTransform()):
        super(LineItem, self).__init__()

        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemIsFocusable)
        self.style = style
        self.boxName = boxName
        self._fromBox = None
        self._toBox = None
        if fromBox == None:
            x1 = 10
            y1 = 10
        else:
            x1 = fromBox.boundingRect().right()
            y1 = fromBox.boundingRect().top(
            ) + fromBox.boundingRect().height() * 0.3
        if toBox == None:
            x2 = 100
            y2 = 100
        else:
            x2 = toBox.boundingRect().left()
            y2 = toBox.boundingRect().top(
            ) + fromBox.boundingRect().height() * 0.3
        self.parentForm = parentForm
        self.source = QPointF(x1, y1)
        self.dest = QPointF(x2, y2)
        self.fromBox = fromBox
        self.toBox = toBox
        self.direction = "a"
        self.myColor = Qt.black
        self.setPen(
            QPen(self.myColor, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 5)
        self.resetLine()
        self.scene = scene
        scene.clearSelection()
        scene.addItem(self)
        self.setSelected(True)
        self.setFocus()
        global Dirty
        Dirty = True

    def resetLine(self):
        if self.fromBox == None and self.toBox == None:
            return
        if self.fromBox == None:
            x2 = self.toBox.x()
            y2 = self.toBox.y() + self.toBox.boundingRect().height() * 0.3
            x1 = x2 - 30
            y1 = y2
        elif self.toBox == None:
            x1 = self.fromBox.x() + self.fromBox.boundingRect().width()
            y1 = self.fromBox.y() + self.fromBox.boundingRect().height() * 0.3
            x2 = x1 + 30
            y2 = y1
        else:
            x_diff = self.toBox.x() - self.fromBox.x()
            y_diff = self.toBox.y() - self.fromBox.y()
            x_diff_standand = (self.fromBox.boundingRect().width() +
                               self.toBox.boundingRect().width()) / 2
            y_diff_standand = (self.fromBox.boundingRect().height() +
                               self.toBox.boundingRect().height()) / 2
            if ((abs(y_diff) < y_diff_standand)):
                if x_diff > 0:

                    self.direction = "x>"
                    x1 = self.fromBox.x() + self.fromBox.boundingRect().width()
                    y1 = self.fromBox.y(
                    ) + self.fromBox.boundingRect().height() * 0.3
                    x2 = self.toBox.x()
                    y2 = self.toBox.y(
                    ) + self.toBox.boundingRect().height() * 0.3
                else:
                    self.direction = "x<"
                    x1 = self.fromBox.x()
                    y1 = self.fromBox.y(
                    ) + self.fromBox.boundingRect().height() * 0.67
                    x2 = self.toBox.x() + self.toBox.boundingRect().width()
                    y2 = self.toBox.y(
                    ) + self.toBox.boundingRect().height() * 0.67
            elif ((abs(x_diff) < x_diff_standand)):
                if (y_diff > 0):
                    self.direction = "y>"
                    x1 = self.fromBox.x(
                    ) + self.fromBox.boundingRect().width() * 0.3
                    y1 = self.fromBox.y() + self.fromBox.boundingRect().height(
                    )
                    x2 = self.toBox.x(
                    ) + self.toBox.boundingRect().width() * 0.3
                    y2 = self.toBox.y()
                else:
                    self.direction = "y<"
                    x1 = self.fromBox.x(
                    ) + self.fromBox.boundingRect().width() * 0.67
                    y1 = self.fromBox.y()
                    x2 = self.toBox.x(
                    ) + self.toBox.boundingRect().width() * 0.67
                    y2 = self.toBox.y() + self.toBox.boundingRect().height()
            else:
                if (x_diff > 0) and (y_diff > 0):
                    self.direction = "xy>"
                    x1 = self.fromBox.x() + self.fromBox.boundingRect().width()
                    y1 = self.fromBox.y(
                    ) + self.fromBox.boundingRect().height() * 0.87
                    x2 = self.toBox.x(
                    ) + self.toBox.boundingRect().width() * 0.13
                    y2 = self.toBox.y()
                elif ((x_diff < 0) and (y_diff < 0)):
                    self.direction = "xy<"
                    x1 = self.fromBox.x()
                    y1 = self.fromBox.y(
                    ) + self.fromBox.boundingRect().height() * 0.13
                    x2 = self.toBox.x(
                    ) + self.toBox.boundingRect().width() * 0.87
                    y2 = self.toBox.y() + self.toBox.boundingRect().height()
                elif (x_diff > 0) and (y_diff < 0):
                    self.direction = "x>y<"
                    x1 = self.fromBox.x(
                    ) + self.fromBox.boundingRect().width() * 0.87
                    y1 = self.fromBox.y()
                    x2 = self.toBox.x()
                    y2 = self.toBox.y(
                    ) + self.toBox.boundingRect().height() * 0.87
                else:
                    self.direction = "x<y>"
                    x1 = self.fromBox.x(
                    ) + self.fromBox.boundingRect().width() * 0.13
                    y1 = self.fromBox.y() + self.fromBox.boundingRect().height(
                    )
                    x2 = self.toBox.x() + self.toBox.boundingRect().width()
                    y2 = self.toBox.y(
                    ) + self.toBox.boundingRect().height() * 0.13
        self.source = QPointF(x1, y1)
        self.dest = QPointF(x2, y2)
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 5)

    @property
    def boxName(self):
        return self._boxName

    @boxName.setter
    def boxName(self, value):
        if not isinstance(value, str):
            raise ValueError('boxName must be an string!')
        self._boxName = value

    def toSaveJson(self):
        data = {
            "type": "Line",
            "boxName": self.boxName,
            "strFromBox": self.fromBox.boxName,
            "strToBox": self.toBox.boxName,
            "style": self.style,
            "rotation": self.rotation()
        }
        return data

    @property
    def fromBox(self):
        return self._fromBox

    @fromBox.setter
    def fromBox(self, value):
        if value != None:
            if not isinstance(value, QGraphicsTextItem):
                raise ValueError('boxName must be an string!')
            self._fromBox = value
            self.resetLine()

    @property
    def toBox(self):
        return self._toBox

    @toBox.setter
    def toBox(self, value):
        if value != None:
            if not isinstance(value, QGraphicsTextItem):
                raise ValueError('boxName must be an string!')
            self._toBox = value
            self.resetLine()

    def parentWidget(self):
        return self.scene().views()[0]

    def itemChange(self, change, variant):
        if change != QGraphicsItem.ItemSelectedChange:
            global Dirty
            Dirty = True
        return QGraphicsLineItem.itemChange(self, change, variant)

    def mouseDoubleClickEvent(self, event):
        dialog = LineItemDlg(self, self.parentWidget(), self.parentWidget(),
                             self.scene, self.parentForm)
        dialog.exec_()

    def paint(self, QPainter, QStyleOptionGraphicsItem, QWidget_widget=None):
        # setPen
        pen = QPen()
        pen.setWidth(1)
        pen.setJoinStyle(Qt.MiterJoin)  #让箭头变尖
        QPainter.setPen(pen)

        # draw line
        QPainter.drawLine(self.line)
        ptextx = (self.line.x1() + self.line.x2()) / 2
        ptexty = (self.line.y1() + self.line.y2()) / 2
        ptexty -= 5
        ptextx -= len(self.boxName) * 3
        QPainter.drawText(QPointF(ptextx, ptexty), self.boxName)

        #Painter.drawText(QPointF(ptextx, ptexty+20), self.direction)
        # setBrush
        brush = QBrush()
        brush.setColor(Qt.black)
        brush.setStyle(Qt.SolidPattern)
        QPainter.setBrush(brush)

        v = self.line.unitVector()
        v.setLength(5)
        v.translate(QPointF(self.line.dx(), self.line.dy()))

        n = v.normalVector()
        n.setLength(n.length() * 0.5)
        n2 = n.normalVector().normalVector()

        p1 = v.p2()
        p2 = n.p2()
        p3 = n2.p2()

        # 方法1
        QPainter.drawLine(self.line)
        QPainter.drawPolygon(p1, p2, p3)

        QPainter.drawArc(10, 10, 50, 50, 0, 180 * 16)

        v = self.line.unitVector()
        v.setLength(5)
        v.translate(QPointF(10, 60))

        n = v.normalVector()
        n.setLength(n.length() * 0.5)
        n2 = n.normalVector().normalVector()

        p1 = v.p2()
        p2 = n.p2()
        p3 = n2.p2()

        # 方法1
        #QPainter.drawLine(self.line)
        QPainter.drawPolygon(p1, p2, p3)
        self.scene.update()
예제 #22
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()
예제 #23
0
class EdgeItem(QGraphicsLineItem):
    def __init__(self,
                 boxName,
                 fromLocation,
                 toLocation,
                 guard,
                 reset,
                 scene,
                 parentForm,
                 style=Qt.SolidLine,
                 rect=None,
                 matrix=QTransform()):
        super(EdgeItem, self).__init__()

        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemIsFocusable)
        self.style = style
        self.boxName = boxName
        self.guard = guard
        self.reset = reset
        self._fromLocation = None
        self._toLocation = None
        if fromLocation == None:
            x1 = 10
            y1 = 10
        else:
            x1 = fromLocation.rect.right()
            y1 = fromLocation.rect.top() + fromLocation.rect.height() * 0.3
        if toLocation == None:
            x2 = 100
            y2 = 100
        else:
            x2 = toLocation.rect.left()
            y2 = toLocation.rect.top() + fromLocation.rect.height() * 0.3
        self.parentForm = parentForm
        self.source = QPointF(x1, y1)
        self.dest = QPointF(x2, y2)
        self.fromLocation = fromLocation
        self.toLocation = toLocation
        self.direction = "a"
        self.myColor = Qt.black
        self.setPen(
            QPen(self.myColor, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 5)
        self.resetLine()
        self.scene = scene
        scene.clearSelection()
        scene.addItem(self)
        self.setSelected(True)
        self.setFocus()
        global Dirty
        Dirty = True

    def drawLine2Self(self):
        haveEdges = [
            strDirection for strDirection in self.fromLocation.edges.values()
        ]
        self.arcx1 = self.fromLocation.x() + self.fromLocation.rect.x(
        ) - 40  #-30
        self.arcy1 = self.fromLocation.y() + self.fromLocation.rect.y(
        )  # -50#+self.fromLocation.rect.height*0.3
        self.minAngle = 90
        x1 = self.arcx1 + 33
        y1 = self.arcy1 + 80
        x2 = self.arcx1 + 40
        y2 = self.arcy1 + 80
        self.arcTextx = self.arcx1
        self.arcTexty = self.arcy1 + 40
        self.spanAngle = 180
        if "top" not in haveEdges and self.fromLocation.isNameAbove == False:
            self.arcx1 = self.fromLocation.x() + self.fromLocation.rect.x(
            ) + 10
            self.arcy1 = self.fromLocation.y() + self.fromLocation.rect.y(
            ) - 40
            x1 = self.arcx1 + 80
            y1 = self.arcy1 + 40 - 7
            x2 = self.arcx1 + 80
            y2 = self.arcy1 + 40
            self.minAngle = 0
            self.arcTextx = self.arcx1 + 40
            self.arcTexty = self.arcy1
        elif "left" not in haveEdges:
            self.arcx1 = self.fromLocation.x() + self.fromLocation.rect.x(
            ) - 40  #-30
            self.arcy1 = self.fromLocation.y() + self.fromLocation.rect.y(
            ) + 10  # -50#+self.fromLocation.rect.height*0.3
            self.minAngle = 90
            x1 = self.arcx1 + 33
            y1 = self.arcy1 + 80
            x2 = self.arcx1 + 40
            y2 = self.arcy1 + 80
            self.arcTextx = self.arcx1
            self.arcTexty = self.arcy1 + 40
        elif "bottom" not in haveEdges and self.fromLocation.isNameAbove:
            self.arcx1 = self.fromLocation.x() + self.fromLocation.rect.x(
            ) + 10
            self.arcy1 = self.fromLocation.y() + self.fromLocation.rect.y(
            ) + self.fromLocation.rect.height() - 40
            self.minAngle = 180
            x1 = self.arcx1 + 80
            y1 = self.arcy1 + 7 + 40
            x2 = self.arcx1 + 80
            y2 = self.arcy1 + 40
            self.arcTextx = self.arcx1 + 40
            self.arcTexty = self.arcy1 + 80
        elif "right" not in haveEdges:
            self.arcx1 = self.fromLocation.x() + self.fromLocation.rect.x(
            ) + self.fromLocation.rect.width() - 40  #-30
            self.arcy1 = self.fromLocation.y() + self.fromLocation.rect.y(
            ) + 10  # -50#+self.fromLocation.rect.height*0.3
            self.minAngle = 270
            x1 = self.arcx1 + 7 + 25 + adjustX1
            y1 = self.arcy1 + 80
            x2 = self.arcx1 + 25 + adjustX1
            y2 = self.arcy1 + 80
            self.arcTextx = self.arcx1 + 80
            self.arcTexty = self.arcy1 + 40
        self.source = QPointF(x1, y1)
        self.dest = QPointF(x2, y2)
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 5)
#if 'time' not in listOfStrings :
#  print("Yes, 'time' NOT found in List : " , listOfStrings)

    def getQPixmap4Guard(self):
        guardFig = Figure(figsize=(5, 0.4))
        canvas = FigureCanvas(guardFig)
        strData = self.guard
        try:
            guardFig.text(0.1, 0.3, strData, family="Consolas", fontsize=10)
        except:
            pass
        canvas.draw()
        size = canvas.size()
        width, height = size.width(), size.height()
        im = QImage(canvas.buffer_rgba(), width, height, QImage.Format_ARGB32)
        return QPixmap(im)

    def getQPixmap4Reset(self):
        guardFig = Figure(figsize=(5, 0.4))
        canvas = FigureCanvas(guardFig)
        strData = self.reset
        try:
            guardFig.text(0.1, 0.3, strData, family="Consolas", fontsize=10)
        except:
            pass
        canvas.draw()
        size = canvas.size()
        width, height = size.width(), size.height()
        im = QImage(canvas.buffer_rgba(), width, height, QImage.Format_ARGB32)
        return QPixmap(im)

    def resetLine(self):
        self.direction = ""
        if self.fromLocation == None and self.toLocation == None:
            return

        if self.fromLocation == None:
            #self.toLocation.edges[self.boxName]="left"
            x2 = self.toLocation.x() + self.toLocation.rect.x()
            y2 = self.toLocation.y() + self.toLocation.rect.x(
            ) + self.toLocation.rect.height() * 0.3
            x1 = x2 - 30
            y1 = y2
        elif self.toLocation == None:
            #self.fromLocation.edges[self.boxName]="right"
            x1 = self.fromLocation.x() + self.fromLocation.rect.x(
            ) + self.fromLocation.rect.width()
            y1 = self.fromLocation.y() + self.fromLocation.rect.y(
            ) + self.fromLocation.rect.height() * 0.3
            x2 = x1 + 30
            y2 = y1
        else:
            adjustX1 = self.fromLocation.x() + self.fromLocation.rect.x()
            adjustX2 = self.toLocation.x() + self.toLocation.rect.x()
            adjustY1 = self.fromLocation.y() + self.fromLocation.rect.y()
            adjustY2 = self.toLocation.y() + self.toLocation.rect.y()
            if self.fromLocation.boxName == self.toLocation.boxName:
                self.drawLine2Self()
                self.fromLocation.edgeToSelf = self.boxName
                return
            x_diff = self.toLocation.x() - self.fromLocation.x()
            y_diff = self.toLocation.y() - self.fromLocation.y()
            x_diff_standand = (self.fromLocation.rect.width() +
                               self.toLocation.rect.width()) / 2
            y_diff_standand = (self.fromLocation.rect.height() +
                               self.toLocation.rect.height()) / 2
            if ((abs(y_diff) < y_diff_standand)):
                if x_diff > 0:

                    self.direction = "x>"

                    self.fromLocation.edges[self.boxName] = "right"
                    self.toLocation.edges[self.boxName] = "left"
                    x1 = self.fromLocation.rect.width() + adjustX1
                    y1 = self.fromLocation.rect.height() * 0.4 + adjustY1
                    x2 = adjustX2
                    y2 = self.toLocation.rect.height() * 0.4 + adjustY2
                else:
                    self.direction = "x<"
                    self.fromLocation.edges[self.boxName] = "left"
                    self.toLocation.edges[self.boxName] = "right"
                    x1 = adjustX1
                    y1 = self.fromLocation.rect.height() * 0.6 + adjustY1
                    x2 = self.toLocation.rect.width() + adjustX2
                    y2 = self.toLocation.rect.height() * 0.6 + adjustY2
            elif ((abs(x_diff) < x_diff_standand)):
                if (y_diff > 0):
                    self.direction = "y>"

                    self.fromLocation.edges[self.boxName] = "bottom"
                    self.toLocation.edges[self.boxName] = "top"
                    x1 = self.fromLocation.rect.width() * 0.4 + adjustX1
                    y1 = self.fromLocation.rect.height() + adjustY1
                    x2 = self.toLocation.rect.width() * 0.4 + adjustX2
                    y2 = adjustY2
                else:
                    self.direction = "y<"
                    self.fromLocation.edges[self.boxName] = "top"
                    self.toLocation.edges[self.boxName] = "bottom"
                    x1 = self.fromLocation.rect.width() * 0.6 + adjustX1
                    y1 = adjustY1
                    x2 = self.toLocation.rect.width() * 0.6 + adjustX2
                    y2 = self.toLocation.rect.height() + adjustY2
            else:
                if (x_diff > 0) and (y_diff > 0):
                    self.direction = "xy>"
                    self.fromLocation.edges[self.boxName] = "right"
                    self.toLocation.edges[self.boxName] = "top"
                    x1 = self.fromLocation.rect.width() + adjustX1
                    y1 = self.fromLocation.rect.height() * 0.8 + adjustY1
                    x2 = self.toLocation.rect.width() * 0.2 + adjustX2
                    y2 = adjustY2
                elif ((x_diff < 0) and (y_diff < 0)):
                    self.direction = "xy<"
                    self.fromLocation.edges[self.boxName] = "left"
                    self.toLocation.edges[self.boxName] = "bottom"
                    x1 = adjustX1
                    y1 = self.fromLocation.rect.height() * 0.2 + adjustY1
                    x2 = self.toLocation.rect.width() * 0.8 + adjustX2
                    y2 = self.toLocation.rect.height() + adjustY2
                elif (x_diff > 0) and (y_diff < 0):
                    self.direction = "x>y<"
                    self.fromLocation.edges[self.boxName] = "top"
                    self.toLocation.edges[self.boxName] = "left"
                    x1 = self.fromLocation.rect.width() * 0.8 + adjustX1
                    y1 = adjustY1
                    x2 = adjustX2
                    y2 = self.toLocation.rect.height() * 0.8 + adjustY2
                else:
                    self.direction = "x<y>"
                    self.fromLocation.edges[self.boxName] = "bottom"
                    self.toLocation.edges[self.boxName] = "right"
                    x1 = self.fromLocation.rect.width() * 0.2 + adjustX1
                    y1 = adjustY1 + self.fromLocation.rect.height()
                    x2 = adjustX2 + self.toLocation.rect.width()
                    y2 = self.toLocation.rect.height() * 0.2 + adjustY2
        self.direction = self.direction + " fLX:" + str(
            self.fromLocation.x()) + ",fLrx" + str(
                self.fromLocation.rect.x()) + ",fLrw" + str(
                    self.fromLocation.rect.width()) + ",Lx" + str(x1)
        self.source = QPointF(x1, y1)
        self.dest = QPointF(x2, y2)
        self.line = QLineF(self.source, self.dest)
        self.line.setLength(self.line.length() - 5)

    @property
    def boxName(self):
        return self._boxName

    @boxName.setter
    def boxName(self, value):
        if not isinstance(value, str):
            raise ValueError('EdgeName must be an string!')
        self._boxName = value

    @property
    def guard(self):
        return self._guard

    @guard.setter
    def guard(self, value):
        if not isinstance(value, str):
            raise ValueError('EdgeName must be an string!')
        self._guard = value

    @property
    def reset(self):
        return self._reset

    @reset.setter
    def reset(self, value):
        if not isinstance(value, str):
            raise ValueError('EdgeName must be an string!')
        self._reset = value

    def toSaveJson(self):
        data = {
            "type": "Edge",
            "boxName": self.boxName,
            "strFromLocation": self.fromLocation.boxName,
            "strToLocation": self.toLocation.boxName,
            "guard": self.guard,
            "reset": self.reset,
            "style": self.style,
            "rotation": self.rotation()
        }

        return data

    @property
    def fromLocation(self):
        return self._fromLocation

    @fromLocation.setter
    def fromLocation(self, value):
        if value != None:
            if not isinstance(value, LocationItem):
                raise ValueError('LocationName must be a  LocationItem!')
            self._fromLocation = value
            self.resetLine()

    @property
    def toLocation(self):
        return self._toLocation

    @toLocation.setter
    def toLocation(self, value):
        if value != None:
            if not isinstance(value, LocationItem):
                raise ValueError('LocationName must be a LocationItem!')
            self._toLocation = value
            self.resetLine()

    def parentWidget(self):
        return self.scene.views()[0]

    def itemChange(self, change, variant):
        if change != QGraphicsItem.ItemSelectedChange:
            global Dirty
            Dirty = True
        return QGraphicsLineItem.itemChange(self, change, variant)

    def mouseDoubleClickEvent(self, event):
        dialog = edgeItemDlg(self, self.parentWidget(), self.parentWidget(),
                             self.scene, self.parentForm)
        dialog.exec_()

    def paint(self, QPainter, QStyleOptionGraphicsItem, QWidget_widget=None):
        # setPen
        pen = QPen()
        pen.setWidth(1)
        pen.setJoinStyle(Qt.MiterJoin)  #让箭头变尖
        QPainter.setPen(pen)

        # draw line
        QPainter.drawLine(self.line)
        ptextx = (self.line.x1() + self.line.x2()) / 2
        ptexty = (self.line.y1() + self.line.y2()) / 2
        ptexty -= 5
        ptextx -= len(self.boxName) * 3

        #QPainter.drawText(QPointF(ptextx, ptexty+20), self.direction)
        # setBrush
        brush = QBrush()
        brush.setColor(Qt.black)
        brush.setStyle(Qt.SolidPattern)
        QPainter.setBrush(brush)

        v = self.line.unitVector()
        v.setLength(5)
        v.translate(QPointF(self.line.dx(), self.line.dy()))

        n = v.normalVector()
        n.setLength(n.length() * 0.5)
        n2 = n.normalVector().normalVector()

        p1 = v.p2()
        p2 = n.p2()
        p3 = n2.p2()

        # 方法1
        QPainter.drawLine(self.line)
        QPainter.drawPolygon(p1, p2, p3)

        if self.fromLocation is not None and self.toLocation is not None:
            if self.fromLocation.boxName == self.toLocation.boxName:
                QPainter.drawArc(self.arcx1, self.arcy1, 80, 80,
                                 self.minAngle * 16, self.spanAngle * 16)
                ptextx = self.arcTextx
                ptexty = self.arcTexty
                #QPainter.drawArc(self.arcx1, self.arcy1+100, 50, 50, 270*16, 89*16)

                #QPainter.drawArc(self.arcx1, self.arcy1+200, 50, 50, 0*16, 89*16)

                #QPainter.drawArc(self.arcx1, self.arcy1+300, 50, 50, 270*16, 180*16)

                #QPainter.drawArc(self.arcx1, self.arcy1+400, 50, 50, 270*16, 270*16)
                #QPainter.drawArc(self.arcx1, self.arcy1+500, 50, 50, 180*16, 89*16)

        QPainter.drawText(QPointF(ptextx, ptexty), self.boxName)

        #QPainter.drawRect(self.arcx1, self.arcy1, 50, 50)
        self.scene.update()
예제 #24
0
class GraphicEdge(QGraphicsPathItem):

    def __init__(self, edge_wrap, directed, parent=None):
        super().__init__(parent)
        self.edge_wrap = edge_wrap
        self.width = 3.0
        self.pos_src = [0, 0]
        self.pos_dst = [0, 0]
        # 是否有向
        self.directed = directed
        self.flag = 0
        self.capacity = self.edge_wrap.capacity

        self.setAcceptHoverEvents(True)
        # 普通画图时的pen样式
        self._n_pen = QPen(QColor("#000"))
        self._n_pen.setWidthF(self.width)
        # 画图时的pen样式
        self._pen = self._n_pen
        # 悬浮时的pen样式
        self._hover_pen = QPen(Qt.green)
        self._hover_pen.setWidthF(self.width)
        # 拖拽时的样式
        self._pen_dragging = QPen(QColor("#000"))
        self._pen_dragging.setStyle(Qt.DashDotLine)
        self._pen_dragging.setWidthF(self.width)

        self._mark_brush = QBrush()
        self._mark_brush.setColor(Qt.green)
        self._mark_brush.setStyle(Qt.SolidPattern)

        self._normal_brush = QBrush()
        self._normal_brush.setColor(Qt.black)
        self._normal_brush.setStyle(Qt.SolidPattern)

        self.brush = self._normal_brush

        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setZValue(-1)

    def set_src(self, x, y):
        self.pos_src = [x, y]

    def set_dst(self, x, y):
        self.pos_dst = [x, y]

    def calc_path(self):
        path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1]))  # 起点
        path.lineTo(QPointF(self.pos_dst[0], self.pos_dst[1]))  # 终点
        if self.directed:
            # 画箭头
            self.line = QLineF(QPointF(self.pos_src[0], self.pos_src[1]), QPointF(self.pos_dst[0], self.pos_dst[1]))
            if self.flag == 0:
                self.line.setLength(self.line.length() - 20)
            else:
                self.line.setLength(self.line.length() - self.edge_wrap.end_item.r)
            v = self.line.unitVector()
            v.setLength(20)
            v.translate(QPointF(self.line.dx(), self.line.dy()))

            n = v.normalVector()
            n.setLength(n.length() * 0.5)
            n2 = n.normalVector().normalVector()

            p1 = v.p2()
            p2 = n.p2()
            p3 = n2.p2()
            # 方法2
            arrow = QPolygonF([p1, p2, p3, p1])
            path.addPolygon(arrow)
        # path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1]))
        # path.lineTo(self.pos_dst[0], self.pos_dst[1])
        return path

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

    def hoverEnterEvent(self, event: 'QGraphicsSceneHoverEvent'):
        self.brush = self._mark_brush
        self._pen = self._hover_pen
        self.update()

    def hoverLeaveEvent(self, event: 'QGraphicsSceneHoverEvent'):
        self.brush = self._normal_brush
        self._pen = self._n_pen
        self.update()

    def shape(self):
        # 设置宽度 这里用了100 很大
        qps = QPainterPathStroker()
        qps.setWidth(100)
        return qps.createStroke(self.calc_path())

    def paint(self, painter, graphics_item, widget=None):

        if self.edge_wrap.end_item is None:
            self.ensureVisible()
            self.setPath(self.calc_path())
            path = self.path()

            painter.setPen(self._pen_dragging)
            painter.setBrush(self.brush)
            painter.drawPath(path)
        else:
            # 这画的才是连接后的线
            self.flag = 1
            self.setPath(self.calc_path())  # 设置路径
            path = self.path()
            painter.setPen(self._pen)
            painter.setBrush(self.brush)
            painter.drawPath(path)
            self.flag = 0
            painter.setFont(QFont("Times New Roman", 16))
            painter.setPen(Qt.red)
            x = int((self.pos_src[0] + self.pos_dst[0]) / 2 - 17)
            y = int((self.pos_src[1] + self.pos_dst[1]) / 2 - 7)
            painter.drawText(x, y, "({}) {}".format(self.edge_wrap.id, self.capacity))
예제 #25
0
    def drawRadar(selfself, qp):
        #set frame:
        qp.setBrush(QBrush(QColor(0, 0, 0), Qt.SolidPattern))
        qp.drawRect(20, 10, 700, 700)

        pen_bold = QPen(QColor(102, 204, 255), 0.8, Qt.SolidLine)

        pen = QPen(QColor(102, 204, 255), 0.8, Qt.DashDotLine)

        pen_hide = QPen(QColor(0, 0, 0), 1.5, Qt.SolidLine)

        #add circle:
        qp.setPen(pen)
        qp.drawEllipse(QPointF(370, 360), 347, 347)

        #add scales:
        for i in range(1, 360):
            if i % 30 == 0:
                pass

            else:
                if i % 10 == 0:
                    scaleLine = QLineF()
                    scaleLine.setP1(QPointF(370, 360))
                    scaleLine.setAngle(i)
                    scaleLine.setLength(347)
                    qp.setPen(pen_bold)
                    qp.drawLine(scaleLine)

                    hideLine = QLineF()
                    hideLine.setP1(QPointF(370, 360))
                    hideLine.setAngle(i)
                    hideLine.setLength(337)
                    qp.setPen(pen_hide)
                    qp.drawLine(hideLine)

                else:
                    scaleLine = QLineF()
                    scaleLine.setP1(QPointF(370, 360))
                    scaleLine.setAngle(i)
                    scaleLine.setLength(347)
                    qp.setPen(pen_bold)
                    qp.drawLine(scaleLine)

                    hideLine = QLineF()
                    hideLine.setP1(QPointF(370, 360))
                    hideLine.setAngle(i)
                    hideLine.setLength(342)
                    qp.setPen(pen_hide)
                    qp.drawLine(hideLine)

        #add other circles:
        qp.setPen(pen)
        qp.drawEllipse(QPointF(370, 360), 277, 277)

        qp.setPen(pen)
        qp.drawEllipse(QPointF(370, 360), 207, 207)

        qp.setPen(pen)
        qp.drawEllipse(QPointF(370, 360), 137, 137)

        qp.setPen(pen)
        qp.drawEllipse(QPointF(370, 360), 67, 67)

        #add lines:
        qp.setPen(pen_bold)
        qp.drawLine(20, 360, 720, 360)

        qp.setPen(pen_bold)
        qp.drawLine(370, 10, 370, 710)

        angleLine1 = QLineF()
        angleLine1.setP1(QPointF(370, 360))
        angleLine1.setAngle(30)
        angleLine1.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine1)

        angleLine2 = QLineF()
        angleLine2.setP1(QPointF(370, 360))
        angleLine2.setAngle(60)
        angleLine2.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine2)

        angleLine3 = QLineF()
        angleLine3.setP1(QPointF(370, 360))
        angleLine3.setAngle(120)
        angleLine3.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine3)

        angleLine4 = QLineF()
        angleLine4.setP1(QPointF(370, 360))
        angleLine4.setAngle(150)
        angleLine4.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine4)

        angleLine5 = QLineF()
        angleLine5.setP1(QPointF(370, 360))
        angleLine5.setAngle(210)
        angleLine5.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine5)

        angleLine6 = QLineF()
        angleLine6.setP1(QPointF(370, 360))
        angleLine6.setAngle(240)
        angleLine6.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine6)

        angleLine7 = QLineF()
        angleLine7.setP1(QPointF(370, 360))
        angleLine7.setAngle(300)
        angleLine7.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine7)

        angleLine8 = QLineF()
        angleLine8.setP1(QPointF(370, 360))
        angleLine8.setAngle(330)
        angleLine8.setLength(347)
        qp.setPen(pen)
        qp.drawLine(angleLine8)
예제 #26
0
 def drawArrows(self, painter):
     """Draws arrows on the board."""
     for highlight in self.highlights:
         if highlight.Type == self.Arrow.Type:
             lineWidth = 10
             sqSize = self.squareSize
             painter.setPen(
                 QPen(highlight.color, lineWidth, Qt.SolidLine,
                      Qt.RoundCap))
             origin = highlight.origin
             target = highlight.target
             dx = target.x() - origin.x()
             dy = target.y() - origin.y()
             # Knight jumps
             if dx == sqSize.width() and dy == -2 * sqSize.height():
                 corner = QPoint(origin.x(),
                                 origin.y() - 2 * sqSize.height())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == 2 * sqSize.width() and dy == -sqSize.height():
                 corner = QPoint(origin.x() + 2 * sqSize.width(),
                                 origin.y())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == 2 * sqSize.width() and dy == sqSize.height():
                 corner = QPoint(origin.x() + 2 * sqSize.width(),
                                 origin.y())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == sqSize.width() and dy == 2 * sqSize.height():
                 corner = QPoint(origin.x(),
                                 origin.y() + 2 * sqSize.height())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == -sqSize.width() and dy == 2 * sqSize.height():
                 corner = QPoint(origin.x(),
                                 origin.y() + 2 * sqSize.height())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == -2 * sqSize.width() and dy == sqSize.height():
                 corner = QPoint(origin.x() - 2 * sqSize.width(),
                                 origin.y())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == -2 * sqSize.width() and dy == -sqSize.height():
                 corner = QPoint(origin.x() - 2 * sqSize.width(),
                                 origin.y())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             elif dx == -sqSize.width() and dy == -2 * sqSize.height():
                 corner = QPoint(origin.x(),
                                 origin.y() - 2 * sqSize.height())
                 line = QLineF(origin, corner)
                 painter.drawLine(line)
                 origin = corner
             # Other moves (and second part of knight jump)
             line = QLineF(origin, target)
             angle = line.angle()
             tip = line.p2()
             line.setLength(line.length() - 2 * lineWidth)
             painter.drawLine(line)
             tipOffset = line.p2()
             leftBase = QLineF()
             leftBase.setP1(tipOffset)
             leftBase.setLength(lineWidth)
             leftBase.setAngle(angle - 90)
             left = leftBase.p2()
             rightBase = QLineF()
             rightBase.setP1(tipOffset)
             rightBase.setLength(lineWidth)
             rightBase.setAngle(angle + 90)
             right = rightBase.p2()
             arrowHead = QPolygonF([left, right, tip])
             path = QPainterPath()
             path.addPolygon(arrowHead)
             painter.fillPath(path, QBrush(highlight.color))
예제 #27
0
 def _boundJoystick(self, point):
     limitLine = QLineF(self._center(), point)
     if (limitLine.length() > self.__maxDistance):
         limitLine.setLength(self.__maxDistance)
     return limitLine.p2()