Ejemplo n.º 1
0
    def addEdge(self,
                startPt,
                endPt,
                label,
                edgeColor,
                labelColor=None,
                xoffset=0.0):
        if not labelColor:
            labelColor = edgeColor

        assert isinstance(startPt, QPointF)
        assert isinstance(endPt, QPointF)
        assert isinstance(label, str)

        # if color in self.edgeList:
        # self.lineList[color].extend( line_list )
        # else:
        # self.lineList[color] = line_list

        # print(self.edgeList)
        edge = QLineF(startPt, endPt)
        if edgeColor in self.edgeList.keys():
            self.edgeList[edgeColor].append(edge)
        else:
            self.edgeList[edgeColor] = [edge]
        # self.update()

        midp = QPointF((edge.x1() * 0.2 + edge.x2() * 0.8),
                       (edge.y1() * 0.2 + edge.y2() * 0.8))
        self.addLabel(midp, label, labelColor, xoffset=xoffset)
Ejemplo n.º 2
0
def get_midpoint(label: str, side: QLineF) -> (QPointF, QPointF):
    """
    Procedure to compute the midpoint of a rectangle side.

    Parameters
    ----------
    label : str
        The side label ("top", "right", "bottom", "left")
    side : QLineF
        The line representing the side.

    Returns
    ----------
    tuple
        The two coordinates of the mid-point.

    """

    mid_x = (side.x1() + side.x2()) / 2
    mid_y = (side.y1() + side.y2()) / 2

    # Add a margin depending on the side
    if label == "top":
        mid_y += 4
    elif label == "right":
        mid_x -= 4
    elif label == "bottom":
        mid_y -= 4
    elif label == "left":
        mid_x += 4

    return mid_x, mid_y
Ejemplo n.º 3
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
Ejemplo n.º 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
Ejemplo n.º 5
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()
Ejemplo n.º 6
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()
Ejemplo n.º 7
0
 def draw_axis(
         painter: QtGui.QPainter,
         axis: QtCore.QLineF,
         pen: QtGui.QPen,
         dash_pen: QtGui.QPen
 ) -> None:
     """ Рисует координатную ось """
     painter.setPen(pen)
     painter.drawLine(
         int(axis.x1()),
         int(axis.y1()),
         int(axis.x2()),
         int(axis.y2())
     )
Ejemplo n.º 8
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
Ejemplo n.º 9
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
    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()
Ejemplo n.º 10
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()
Ejemplo n.º 11
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()
Ejemplo n.º 12
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()
Ejemplo n.º 13
0
def line_q_to_s(line: QLineF):
    return Line(Point(line.x1(), line.y1()), Point(line.x2(), line.y2()))
Ejemplo n.º 14
0
 def draw_axis(painter: QtGui.QPainter, axis: QtCore.QLineF, pen,
               dash_pen) -> None:
     painter.setPen(pen)
     painter.drawLine(0, 0, int(axis.x1()), int(axis.y1()))
     painter.setPen(dash_pen)
     painter.drawLine(0, 0, int(axis.x2()), int(axis.y2()))