예제 #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)
예제 #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
예제 #3
0
class Border(QGraphicsItem):
    #def __init__(self, x, y, width, height, vx, vy):
    def __init__(self, x1, y1, x2, y2, dir):
        super(Border, self).__init__()
        #self.pos = QPointF(x, y)
        #self.lines = [QLineF(x, y, x + width, y),
        #              QLineF(x, y, x, y + height),
        #              QLineF(x, y + height, x + width, y + height),
        #              QLineF(x + width, y, x + width, y + height)]
        #self.width = width
        #self.height = height
        #self.rect = QRectF(self.pos.x(), self.pos.y(), self.width, self.height)
        if dir == 1:
            self.line = QLineF(x1, y1, x2, y2)
        else:
            self.line = QLineF(x2, y2, x1, y1)

        #self.direction = QVector2D(vx, vy)

    def type(self):
        return QGraphicsItem.UserType + 1

    # def collisionAngle(self, line):
    #     intersects = (None, 0)
    #     for l in self.lines:
    #         r = line.intersects(l)
    #         print (r, l, line)
    #         if r[0] == 1:
    #             tmp = QLineF(line.p1(), r[1])
    #             if intersects[0] is None or tmp.length() < intersects[1]:
    #                 print ("raggio ", tmp, tmp.length()) # corretto
    #                 print ("l ", l, tmp.angleTo(l))
    #                 print ("l_perp ", l.normalVector(), tmp.angleTo(l.normalVector()))
    #                 intersects = [tmp, tmp.length(), tmp.angleTo(l.normalVector())]
    #                 print ("inter ", intersects)
    #
    #     if intersects[0] is not None:
    #         return intersects[2]
    #     else:
    #         return 0

    def boundingRect(self):
        #return QRectF(self.pos.x(), self.pos.y(), self.width, self.height)
        return QRectF(self.line.x1(), self.line.y1(),
                      self.line.dx() + 2,
                      self.line.dy() + 2)

    def paint(self, painter, option, widget):
        #painter.setRenderHint(QPainter::Antialiasing);
        #painter.setPen(Qt::black);
        painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
        painter.setBrush(QBrush(Qt.red, Qt.VerPattern))
        painter.drawLine(self.line)
예제 #4
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())
     )
예제 #5
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()
예제 #6
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()
예제 #7
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()
예제 #8
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()
예제 #9
0
def line_q_to_s(line: QLineF):
    return Line(Point(line.x1(), line.y1()), Point(line.x2(), line.y2()))
예제 #10
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()))