Esempio n. 1
0
 def plotOutline(self, vertexs):
     scene = self.view.getScene()
     
     polygon = QPolygonF()
     polygon.clear()
     for point in vertexs:
         polygon.append(QPointF(point[0] * consts.DPM_X, point[1] * consts.DPM_Y))
     scene.addPolygon(polygon, QColor(0,0,128))
Esempio n. 2
0
 def SetPoly(self, pos: QPointF):
     x, y = pos.x(), pos.y()
     if self.m_Item:
         self.removeItem(self.m_Item)
     poly = QPolygonF()
     poly.clear()
     poly.append(QPointF(x, y))
     poly.append(QPointF(x + 100, y))
     poly.append(QPointF(x + 200, y - 100))
     poly.append(QPointF(x - 100, y - 100))
     bursh = QBrush(QColor(123, 123, 123, 80))
     pen = QPen(QtCore.Qt.red)
     self.m_Item = self.addPolygon(poly, pen, bursh)
Esempio n. 3
0
class Arrow(QGraphicsLineItem):
    def __init__(self, startItem, endItem, parent=None, scene=None):
        super(Arrow, self).__init__(parent)

        self.arrowHead = QPolygonF()

        self.myStartItem = startItem
        self.myEndItem = endItem
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.myColor = Qt.black
        self.setPen(QPen(self.myColor, 2, Qt.SolidLine, Qt.RoundCap,
                Qt.RoundJoin))

    def setColor(self, color):
        self.myColor = color

    def startItem(self):
        return self.myStartItem

    def endItem(self):
        return self.myEndItem

    def boundingRect(self):
        extra = (self.pen().width() + 20) / 2.0
        p1 = self.line().p1()
        p2 = self.line().p2()
        return QRectF(p1, QSizeF(p2.x() - p1.x(), p2.y() - p1.y())).normalized().adjusted(-extra, -extra, extra, extra)

    def shape(self):
        path = super(Arrow, self).shape()
        path.addPolygon(self.arrowHead)
        return path

    def updatePosition(self):
        line = QLineF(self.mapFromItem(self.myStartItem, 0, 0), self.mapFromItem(self.myEndItem, 0, 0))
        self.setLine(line)

    def paint(self, painter, option, widget=None):
        if (self.myStartItem.collidesWithItem(self.myEndItem)):
            return

        myStartItem = self.myStartItem
        myEndItem = self.myEndItem
        myColor = self.myColor
        myPen = self.pen()
        myPen.setColor(self.myColor)
        arrowSize = 20.0
        painter.setPen(myPen)
        painter.setBrush(self.myColor)

        centerLine = QLineF(myStartItem.pos(), myEndItem.pos())
        endPolygon = myEndItem.polygon()
        p1 = endPolygon.first() + myEndItem.pos()

        intersectPoint = QPointF()
        for i in endPolygon:
            p2 = i + myEndItem.pos()
            polyLine = QLineF(p1, p2)
            intersectType = polyLine.intersect(centerLine, intersectPoint)
            if intersectType == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersectPoint, myStartItem.pos()))
        line = self.line()

        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi * 2.0) - angle

        arrowP1 = line.p1() + QPointF(math.sin(angle + math.pi / 3.0) * arrowSize,
                                        math.cos(angle + math.pi / 3) * arrowSize)
        arrowP2 = line.p1() + QPointF(math.sin(angle + math.pi - math.pi / 3.0) * arrowSize,
                                        math.cos(angle + math.pi - math.pi / 3.0) * arrowSize)

        self.arrowHead.clear()
        for point in [line.p1(), arrowP1, arrowP2]:
            self.arrowHead.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(myColor, 1, Qt.DashLine))
            myLine = QLineF(line)
            myLine.translate(0, 4.0)
            painter.drawLine(myLine)
            myLine.translate(0,-8.0)
            painter.drawLine(myLine)
Esempio n. 4
0
class Arrow(QGraphicsLineItem):
    def __init__(self, start_item, end_item, parent=None):
        super(Arrow, self).__init__(parent)

        self.arrowHead = QPolygonF()

        self.my_start_item = start_item
        self.my_end_item = end_item
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.my_color = Qt.black
        self.setPen(QPen(self.my_color, 2, Qt.SolidLine, Qt.RoundCap,
                         Qt.RoundJoin))

    def set_color(self, color):
        self.my_color = color

    def start_item(self):
        return self.my_start_item

    def end_item(self):
        return self.my_end_item

    def boundingRect(self):
        extra = (self.pen().width() + 20) / 2.0
        p1 = self.line().p1()
        p2 = self.line().p2()
        return QRectF(p1, QSizeF(p2.x() - p1.x(), p2.y() - p1.y())).normalized().adjusted(-extra, -extra, extra, extra)

    def shape(self):
        path = super(Arrow, self).shape()
        path.addPolygon(self.arrowHead)
        return path

    def update_position(self):
        line = QLineF(self.mapFromItem(self.my_start_item, 0, 0), self.mapFromItem(self.my_end_item, 0, 0))
        self.setLine(line)

    def paint(self, painter, option, widget=None):
        if self.my_start_item.collidesWithItem(self.my_end_item):
            return

        my_start_item = self.my_start_item
        my_end_item = self.my_end_item
        my_color = self.my_color
        my_pen = self.pen()
        my_pen.setColor(self.my_color)
        arrow_size = 20.0
        painter.setPen(my_pen)
        painter.setBrush(my_color)

        center_line = QLineF(my_start_item.pos(), my_end_item.pos())
        end_polygon = my_end_item.polygon

        p1 = end_polygon.first() + my_end_item.pos()

        intersect_point = QPointF()
        for i in end_polygon:
            p2 = i + my_end_item.pos()
            poly_line = QLineF(p1, p2)
            intersect_type = poly_line.intersect(center_line, intersect_point)
            if intersect_type == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersect_point, my_start_item.pos()))
        line = self.line()

        angle = math.acos(line.dx() / line.length())

        if line.dy() >= 0:
            angle = (math.pi * 2) - angle

        arrow_p1 = line.p1() + QPointF(math.sin(angle + math.pi / 3.0) * arrow_size,
                                       math.cos(angle + math.pi / 3) * arrow_size)
        arrow_p2 = line.p1() + QPointF(math.sin(angle + math.pi - math.pi / 3.0) * arrow_size,
                                       math.cos(angle + math.pi - math.pi / 3.0) * arrow_size)

        self.arrowHead.clear()
        for point in [line.p1(), arrow_p1, arrow_p2]:
            self.arrowHead.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(my_color, 1, Qt.DashLine))
            my_line = QLineF(line)
            my_line.translate(0, 4.0)
            painter.drawLine(my_line)
            my_line.translate(0, -8.0)
            painter.drawLine(my_line)
class MovableArrow(QGraphicsLineItem):

    def __init__(self, parent=None):
        super(MovableArrow, self).__init__(parent)
        self.setZValue(1000)

        self.arrowHead = QPolygonF()
        self.begin = np.array([0.0, 0.0])
        self.end =np.array([10.0, 10.0])

        self.myColor = Qt.black
        self.setPen(QPen(self.myColor, 5))
        self.arrowSize = 5
        self.setOpacity(0.4)

        self.isMousePressed = False
        self.setFlags(QGraphicsItem.ItemIsSelectable |
                      QGraphicsItem.ItemIsFocusable |
                      QGraphicsItem.ItemIsMovable |
                      QGraphicsItem.ItemSendsGeometryChanges)


        self.angleFixedFlag = False
        self.objectName = None
    def boundingRect(self):
        extra = (self.pen().width() + 20) / 2.0
        size = QSizeF(
                1.3*(self.line().p1().x() - self.line().p2().x()),
                1.3*(self.line().p1().y() - self.line().p2().y())
                )

        return QRectF(self.line().p2(), size).normalized().adjusted(-extra, -extra, extra, extra)

    def shape(self):
        path = super(MovableArrow, self).shape()
        path.addPolygon(self.arrowHead)
        return path

    def setColor(self, colorArray):
        self.myColor = QColor(*colorArray)

    def updatePosition(self):
        line = QLineF(QPointF(*self.end), QPointF(*self.begin))
        self.setLine(line)
        self.shape()

    def paint(self, painter, option, widget=None):
        self.updatePosition()

        myPen = self.pen()
        myPen.setColor(self.myColor)
        painter.setPen(myPen)
        # painter.setBrush(self.myColor)

        try:
            angle = np.arccos(self.line().dx() / self.line().length())
        except ZeroDivisionError:
            angle = 0.0
        if self.line().dy() >= 0:
            angle = (np.pi * 2) - angle;

        l = self.line().length()*0.1
        arrowP0 = self.line().p1() - QPointF(self.line().dx()/l, self.line().dy()/l)

        arrowP1 = self.line().p1() + QPointF(np.sin(angle + np.pi / 6) * self.arrowSize,
                                        np.cos(angle + np.pi / 6) * self.arrowSize)
        arrowP2 = self.line().p1() + QPointF(np.sin(angle + np.pi - np.pi / 6) * self.arrowSize,
                                        np.cos(angle + np.pi - np.pi / 6) * self.arrowSize)

        self.arrowHead.clear();
        self.arrowHead.append(arrowP0)
        self.arrowHead.append(arrowP1)
        self.arrowHead.append(arrowP2)

        # painter.drawConvexPolygon(self.arrowHead)
        arrow = QPainterPath()
        arrow.addPolygon(self.arrowHead)
        painter.fillPath(arrow, QBrush(self.myColor))

        painter.drawLine(self.line())

        self.shape()

    def mousePressEvent(self, event):
        self.isMousePressed = True
        self.mousePressedPos = event.scenePos()
        self.end_old = self.end.copy()
        super(MovableArrow, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        mouseCursorPos = event.scenePos()
        #mouseCursorPos = event.Pos()
        if self.isMousePressed:
            x = mouseCursorPos.x() - self.mousePressedPos.x()
            y = mouseCursorPos.y() - self.mousePressedPos.y()
            delta = np.array([x,y])
            # angle = ang(self.begin, self.end+delta)
            if self.angleFixedFlag == False:
                self.end[:] = self.end_old + delta
            else:
                T = self.end_old-self.begin
                delta = delta
                self.end[:] = self.begin+((T)/np.linalg.norm(T))*np.linalg.norm(delta)
                
            self.updatePosition()
        #super(MovableArrow, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self.isMousePressed = False
        super(MovableArrow, self).mouseReleaseEvent(event)
        
    def getVector(self):
        return self.end-self.begin
    def setObjectName(self,name):
        self.objectName = name
    def objectName(self):
        return self.objectName
Esempio n. 6
0
class Arrow(QGraphicsLineItem):
    def __init__(self, startp=Point(), endp=None,
                 length=60.0, angle=50.0,
                 color=QtCore.Qt.red, pencolor=QtCore.Qt.green,
                 startarrow=True):
        """
        Initialisation of the class.
        """
        self.sc = None
        super(Arrow, self).__init__()

        self.startp = QtCore.QPointF(startp.x, -startp.y)
        self.endp = endp

        self.length = length
        self.angle = angle
        self.startarrow = startarrow
        self.allwaysshow = False

        self.arrowHead = QPolygonF()
        self.setFlag(QGraphicsItem.ItemIsSelectable, False)
        self.myColor = color
        self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine)
        self.pen.setCosmetic(True)
        self.arrowSize = 8.0

    def contains_point(self, point):
        """
        Arrows cannot be selected. Return maximal distance
        """
        return float(0x7fffffff)

    def setSelected(self, flag=True, blockSignals=True):
        """
        Override inherited function to turn off selection of Arrows.
        @param flag: The flag to enable or disable Selection
        """
        if self.allwaysshow:
            pass
        elif flag is True:
            self.show()
        else:
            self.hide()

    def setallwaysshow(self, flag=False):
        """
        If the directions shall be allwaysshown the parameter
        will be set and  all paths will be shown.
        @param flag: The flag to enable or disable Selection
        """
        self.allwaysshow = flag
        if flag is True:
            self.show()
        elif flag is True and self.isSelected():
            self.show()
        else:
            self.hide()

    def paint(self, painter, option, widget=None):
        """
        Method for painting the arrow.
        """

        demat = painter.deviceTransform()
        self.sc = demat.m11()

        if self.endp is None:
            dx = cos(self.angle) * self.length / self.sc
            dy = sin(self.angle) * self.length / self.sc

            endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy)
        else:
            endp = QtCore.QPointF(self.endp.x, -self.endp.y)

        arrowSize = self.arrowSize / self.sc

        painter.setPen(self.pen)
        painter.setBrush(self.myColor)

        self.setLine(QtCore.QLineF(endp, self.startp))
        line = self.line()

        if line.length() != 0:
            angle = acos(line.dx() / line.length())

            if line.dy() >= 0:
                angle = (pi * 2.0) - angle

            if self.startarrow:
                arrowP1 = line.p2() - QtCore.QPointF(sin(angle + pi / 3.0) * arrowSize,
                                                     cos(angle + pi / 3.0) * arrowSize)
                arrowP2 = line.p2() - QtCore.QPointF(sin(angle + pi - pi / 3.0) * arrowSize,
                                                     cos(angle + pi - pi / 3.0) * arrowSize)
                self.arrowHead.clear()
                for Point in [line.p2(), arrowP1, arrowP2]:
                    self.arrowHead.append(Point)

            else:
                arrowP1 = line.p1() + QtCore.QPointF(sin(angle + pi / 3.0) * arrowSize,
                                                     cos(angle + pi / 3.0) * arrowSize)
                arrowP2 = line.p1() + QtCore.QPointF(sin(angle + pi - pi / 3.0) * arrowSize,
                                                     cos(angle + pi - pi / 3.0) * arrowSize)
                self.arrowHead.clear()
                for Point in [line.p1(), arrowP1, arrowP2]:
                    self.arrowHead.append(Point)

            painter.drawLine(line)
            painter.drawPolygon(self.arrowHead)

    def boundingRect(self):
        """
        Override inherited function to enlarge selection of Arrow to include all
        @param flag: The flag to enable or disable Selection
        """
        if not self.sc:  # since this function is called before paint; and scale is unknown
            return QtCore.QRectF(self.startp.x(), self.startp.y(), 1e-9, 1e-9)

        arrowSize = self.arrowSize / self.sc
        extra = arrowSize  # self.pen.width() +

        if self.endp is None:
            dx = cos(self.angle) * self.length / self.sc
            dy = sin(self.angle) * self.length / self.sc

            endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy)
        else:
            endp = QtCore.QPointF(self.endp.x, -self.endp.y)

        brect = QtCore.QRectF(self.startp,
                              QtCore.QSizeF(endp.x()-self.startp.x(),
                                            endp.y()-self.startp.y())).normalized().adjusted(-extra, -extra, extra, extra)
        return brect
Esempio n. 7
0
class ArrowItem(QGraphicsLineItem):

    def __init__(self, *args, has_head=True, has_tail=False, **kwargs):
        super().__init__(*args, **kwargs)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setPen(QPen(Qt.black, 10, Qt.SolidLine))
        self._has_head = has_head
        self._has_tail = has_tail
        self._arrow_head = QPolygonF()
        self._arrow_tail = QPolygonF()

    def hasTail(self):
        return self._has_tail

    def setTail(self, visible: bool):
        if self._has_tail != visible:
            self._has_tail = visible
            self.update()

    def hasHead(self):
        return self._has_head

    def setHead(self, visible: bool):
        if self._has_head != visible:
            self._has_head = visible
            self.update()

    def getAngle(self):
        dx, dy = self.line().dx(), self.line().dy()
        return math.pi - math.atan(dx / dy) if dy != 0 else math.copysign(math.pi / 2, dx)

    def shape(self):
        path = QPainterPath()
        stroker = QPainterPathStroker()
        path.moveTo(self.line().p1())
        path.lineTo(self.line().p2())
        path.addPolygon(self._arrow_head)
        path.addPolygon(self._arrow_tail)
        stroker.setWidth(self.pen().width())
        return stroker.createStroke(path)

    def boundingRect(self) -> QRectF:
        return self.shape().boundingRect()

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: Optional[QWidget] = None) -> None:
        painter.setRenderHint(QPainter.Antialiasing)
        pen = self.pen()
        brush = QBrush()
        if self.isSelected():
            color = QColor(255, 0, 0)
            pen.setColor(color)
        else:
            color = pen.color()

        painter.setPen(pen)
        brush.setColor(color)
        brush.setStyle(Qt.SolidPattern)
        painter.setBrush(brush)
        painter.drawLine(self.line())

        angle = self.getAngle()
        if self.line().dy() >= 0.:
            angle += math.pi
        size = self.pen().width() * 2.5

        if self._has_tail or self._has_head:
            painter.setPen(QPen(color, self.pen().width(), Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

        if self._has_tail:
            a = angle + math.pi + math.pi * .1
            b = angle + math.pi - math.pi * .1
            p0 = self.line().p1() + QPointF(math.sin(angle) * self.pen().width(),
                                            -math.cos(angle) * self.pen().width())
            p1 = p0 + QPointF(math.sin(a) * size, -math.cos(a) * size)
            p2 = p0 + QPointF(math.sin(b) * size, -math.cos(b) * size)
            self._arrow_tail.clear()
            self._arrow_tail << p0 << p1 << p2
            painter.drawPolygon(self._arrow_tail)

        if self._has_head:
            a = angle + math.pi * .1
            b = angle - math.pi * .1
            p0 = self.line().p2() - QPointF(math.sin(angle) * self.pen().width(),
                                            -math.cos(angle) * self.pen().width())
            p1 = p0 + QPointF(math.sin(a) * size, -math.cos(a) * size)
            p2 = p0 + QPointF(math.sin(b) * size, -math.cos(b) * size)
            self._arrow_head.clear()
            self._arrow_head << p0 << p1 << p2
            painter.drawPolygon(self._arrow_head)

    def __str__(self):
        return 'Arrow' if self.hasHead() or self.hasTail() else 'Line'
Esempio n. 8
0
class Arrow(QGraphicsLineItem):
    def __init__(self,
                 startp=Point(),
                 endp=None,
                 length=60.0,
                 angle=50.0,
                 color=QtCore.Qt.red,
                 pencolor=QtCore.Qt.green,
                 startarrow=True):
        """
        Initialisation of the class.
        """
        self.sc = None
        super(Arrow, self).__init__()

        self.startp = QtCore.QPointF(startp.x, -startp.y)
        self.endp = endp

        self.length = length
        self.angle = angle
        self.startarrow = startarrow
        self.allwaysshow = False

        self.arrowHead = QPolygonF()
        self.setFlag(QGraphicsItem.ItemIsSelectable, False)
        self.myColor = color
        self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine)
        self.pen.setCosmetic(True)
        self.arrowSize = 8.0

    def contains_point(self, point):
        """
        Arrows cannot be selected. Return maximal distance
        """
        return float(0x7fffffff)

    def setSelected(self, flag=True, blockSignals=True):
        """
        Override inherited function to turn off selection of Arrows.
        @param flag: The flag to enable or disable Selection
        """
        if self.allwaysshow:
            pass
        elif flag is True:
            self.show()
        else:
            self.hide()

    def setallwaysshow(self, flag=False):
        """
        If the directions shall be allwaysshown the parameter
        will be set and  all paths will be shown.
        @param flag: The flag to enable or disable Selection
        """
        self.allwaysshow = flag
        if flag is True:
            self.show()
        elif flag is True and self.isSelected():
            self.show()
        else:
            self.hide()

    def paint(self, painter, option, widget=None):
        """
        Method for painting the arrow.
        """

        demat = painter.deviceTransform()
        self.sc = demat.m11()

        if self.endp is None:
            dx = cos(self.angle) * self.length / self.sc
            dy = sin(self.angle) * self.length / self.sc

            endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy)
        else:
            endp = QtCore.QPointF(self.endp.x, -self.endp.y)

        arrowSize = self.arrowSize / self.sc

        painter.setPen(self.pen)
        painter.setBrush(self.myColor)

        self.setLine(QtCore.QLineF(endp, self.startp))
        line = self.line()

        if line.length() != 0:
            angle = acos(line.dx() / line.length())

            if line.dy() >= 0:
                angle = (pi * 2.0) - angle

            if self.startarrow:
                arrowP1 = line.p2() - QtCore.QPointF(
                    sin(angle + pi / 3.0) * arrowSize,
                    cos(angle + pi / 3.0) * arrowSize)
                arrowP2 = line.p2() - QtCore.QPointF(
                    sin(angle + pi - pi / 3.0) * arrowSize,
                    cos(angle + pi - pi / 3.0) * arrowSize)
                self.arrowHead.clear()
                for Point in [line.p2(), arrowP1, arrowP2]:
                    self.arrowHead.append(Point)

            else:
                arrowP1 = line.p1() + QtCore.QPointF(
                    sin(angle + pi / 3.0) * arrowSize,
                    cos(angle + pi / 3.0) * arrowSize)
                arrowP2 = line.p1() + QtCore.QPointF(
                    sin(angle + pi - pi / 3.0) * arrowSize,
                    cos(angle + pi - pi / 3.0) * arrowSize)
                self.arrowHead.clear()
                for Point in [line.p1(), arrowP1, arrowP2]:
                    self.arrowHead.append(Point)

            painter.drawLine(line)
            painter.drawPolygon(self.arrowHead)

    def boundingRect(self):
        """
        Override inherited function to enlarge selection of Arrow to include all
        @param flag: The flag to enable or disable Selection
        """
        if not self.sc:  # since this function is called before paint; and scale is unknown
            return QtCore.QRectF(self.startp.x(), self.startp.y(), 1e-9, 1e-9)

        arrowSize = self.arrowSize / self.sc
        extra = arrowSize  # self.pen.width() +

        if self.endp is None:
            dx = cos(self.angle) * self.length / self.sc
            dy = sin(self.angle) * self.length / self.sc

            endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy)
        else:
            endp = QtCore.QPointF(self.endp.x, -self.endp.y)

        brect = QtCore.QRectF(
            self.startp,
            QtCore.QSizeF(endp.x() - self.startp.x(),
                          endp.y() - self.startp.y())).normalized().adjusted(
                              -extra, -extra, extra, extra)
        return brect
Esempio n. 9
0
class ContOverlay(AbstractOverlay):
    '''Definie contour item
    '''
    def __init__(self, widget):
        super().__init__(widget)
        self.freehandDone = None
        # fill dummydata
        self.contour = QPolygonF()
        self.contour.append(QPointF(23, 24))
        self.contour.append(QPointF(50, 50))
        self.contour.append(QPointF(21, 76))
        self.freeHandPath = QPolygonF()
        self.curmouspos = QPoint()

    def handleEvent(self, event) -> bool:
        trf = self.invertedTransform()
        processed = False

        if event.type() == QEvent.MouseButtonPress:
            self.freeHandPath.clear()
            trfmpos = trf.map(event.pos())
            self.freeHandPath.append(trfmpos)
            processed = True
        elif event.type(
        ) == QEvent.MouseMove and event.buttons() & Qt.LeftButton:
            trfmpos = trf.map(event.pos())
            self.freeHandPath.append(trfmpos)
            processed = True
        elif event.type() == QEvent.MouseMove:
            # mouse move without button pressed
            self.curmouspos = event.pos()
            self.widget.update()
        elif event.type() == QEvent.MouseButtonRelease:
            processed = True
            if self.freehandDone:
                self.freehandDone(event.pos())
        if processed:
            self.widget.update()

        return processed

    def render(self, painter):
        if self.active:
            trf = self.transform()
            painter.setPen(QPen(Qt.white, 5))
            cont = trf.map(self.contour)
            painter.drawPolygon(cont)
            if len(self.freeHandPath) > 0:
                pen = QPen(QColor(255, 255, 255, 180), 22)
                pen.setCapStyle(Qt.RoundCap)
                pen.setJoinStyle(Qt.RoundJoin)
                painter.setPen(pen)
                fh = trf.map(self.freeHandPath)
                painter.drawPolyline(fh)
            else:
                # zeichnen einer kreis, zur suggestion
                painter.setPen(QPen(Qt.black, 1))
                painter.drawEllipse(self.curmouspos, 11, 11)

    def enter(self):
        self.freeHandPath.clear()
        self.active = True
        self.widget.update()

    def leave(self):
        self.freeHandPath.clear()
        self.active = False
        self.widget.update()
Esempio n. 10
0
    def paintEvent(self, event):
        page_bottom = self.edit.viewport().height()
        font_metrics = QFontMetrics(self.edit.document().defaultFont())
        current_block = self.edit.document().findBlock(
            self.edit.textCursor().position())
        pattern = self.pat if self.edit.lang == "python" else self.patNotPython

        painter = QPainter(self)
        background = resources.CUSTOM_SCHEME.get('sidebar-background',
            resources.COLOR_SCHEME['sidebar-background'])
        foreground = resources.CUSTOM_SCHEME.get('sidebar-foreground',
            resources.COLOR_SCHEME['sidebar-foreground'])
        pep8color = resources.CUSTOM_SCHEME.get('pep8-underline',
            resources.COLOR_SCHEME['pep8-underline'])
        errorcolor = resources.CUSTOM_SCHEME.get('error-underline',
            resources.COLOR_SCHEME['error-underline'])
        migrationcolor = resources.CUSTOM_SCHEME.get('migration-underline',
            resources.COLOR_SCHEME['migration-underline'])
        painter.fillRect(self.rect(), QColor(background))

        block = self.edit.firstVisibleBlock()
        viewport_offset = self.edit.contentOffset()
        line_count = block.blockNumber()
        painter.setFont(self.edit.document().defaultFont())
        while block.isValid():
            line_count += 1
            # The top left position of the block in the document
            position = self.edit.blockBoundingGeometry(block).topLeft() + \
                viewport_offset
            # Check if the position of the block is outside of the visible area
            if position.y() > page_bottom:
                break

            # Set the Painter Pen depending on special lines
            error = False
            if settings.CHECK_STYLE and \
               ((line_count - 1) in self._pep8Lines):
                painter.setPen(QColor(pep8color))
                font = painter.font()
                font.setItalic(True)
                font.setUnderline(True)
                painter.setFont(font)
                error = True
            elif settings.FIND_ERRORS and \
                 ((line_count - 1) in self._errorsLines):
                painter.setPen(QColor(errorcolor))
                font = painter.font()
                font.setItalic(True)
                font.setUnderline(True)
                painter.setFont(font)
                error = True
            elif settings.SHOW_MIGRATION_TIPS and \
                 ((line_count - 1) in self._migrationLines):
                painter.setPen(QColor(migrationcolor))
                font = painter.font()
                font.setItalic(True)
                font.setUnderline(True)
                painter.setFont(font)
                error = True
            else:
                painter.setPen(QColor(foreground))

            # We want the line number for the selected line to be bold.
            bold = False
            if block == current_block:
                bold = True
                font = painter.font()
                font.setBold(True)
                painter.setFont(font)

            # Draw the line number right justified at the y position of the
            # line. 3 is a magic padding number. drawText(x, y, text).
            if block.isVisible():
                painter.drawText(self.width() - self.foldArea -
                    font_metrics.width(str(line_count)) - 3,
                    round(position.y()) + font_metrics.ascent() +
                    font_metrics.descent() - 1,
                    str(line_count))

            # Remove the bold style if it was set previously.
            if bold:
                font = painter.font()
                font.setBold(False)
                painter.setFont(font)
            if error:
                font = painter.font()
                font.setItalic(False)
                font.setUnderline(False)
                painter.setFont(font)

            block = block.next()

        self.highest_line = line_count

        #Code Folding
        xofs = self.width() - self.foldArea
        painter.fillRect(xofs, 0, self.foldArea, self.height(),
                QColor(resources.CUSTOM_SCHEME.get('fold-area',
                resources.COLOR_SCHEME['fold-area'])))
        if self.foldArea != self.rightArrowIcon.width():
            polygon = QPolygonF()

            self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea)
            self.rightArrowIcon.fill(Qt.transparent)
            self.downArrowIcon = QPixmap(self.foldArea, self.foldArea)
            self.downArrowIcon.fill(Qt.transparent)

            polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25))
            polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75))
            polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5))
            iconPainter = QPainter(self.rightArrowIcon)
            iconPainter.setRenderHint(QPainter.Antialiasing)
            iconPainter.setPen(Qt.NoPen)
            iconPainter.setBrush(QColor(
                resources.CUSTOM_SCHEME.get('fold-arrow',
                resources.COLOR_SCHEME['fold-arrow'])))
            iconPainter.drawPolygon(polygon)

            polygon.clear()
            polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4))
            polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4))
            polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8))
            iconPainter = QPainter(self.downArrowIcon)
            iconPainter.setRenderHint(QPainter.Antialiasing)
            iconPainter.setPen(Qt.NoPen)
            iconPainter.setBrush(QColor(
                resources.CUSTOM_SCHEME.get('fold-arrow',
                resources.COLOR_SCHEME['fold-arrow'])))
            iconPainter.drawPolygon(polygon)

        block = self.edit.firstVisibleBlock()
        while block.isValid():
            position = self.edit.blockBoundingGeometry(
                block).topLeft() + viewport_offset
            #Check if the position of the block is outside of the visible area
            if position.y() > page_bottom:
                break

            if pattern.match(block.text()) and block.isVisible():
                if block.blockNumber() in self._foldedBlocks:
                    painter.drawPixmap(xofs, round(position.y()),
                        self.rightArrowIcon)
                else:
                    painter.drawPixmap(xofs, round(position.y()),
                        self.downArrowIcon)
            #Add Bookmarks and Breakpoint
            elif block.blockNumber() in self._breakpoints:
                linear_gradient = QLinearGradient(
                    xofs, round(position.y()),
                    xofs + self.foldArea, round(position.y()) + self.foldArea)
                linear_gradient.setColorAt(0, QColor(255, 11, 11))
                linear_gradient.setColorAt(1, QColor(147, 9, 9))
                painter.setRenderHints(QPainter.Antialiasing, True)
                painter.setPen(Qt.NoPen)
                painter.setBrush(QBrush(linear_gradient))
                painter.drawEllipse(
                    xofs + 1,
                    round(position.y()) + 6,
                    self.foldArea - 1, self.foldArea - 1)
            elif block.blockNumber() in self._bookmarks:
                linear_gradient = QLinearGradient(
                    xofs, round(position.y()),
                    xofs + self.foldArea, round(position.y()) + self.foldArea)
                linear_gradient.setColorAt(0, QColor(13, 62, 243))
                linear_gradient.setColorAt(1, QColor(5, 27, 106))
                painter.setRenderHints(QPainter.Antialiasing, True)
                painter.setPen(Qt.NoPen)
                painter.setBrush(QBrush(linear_gradient))
                painter.drawRoundedRect(
                    xofs + 1,
                    round(position.y()) + 6,
                    self.foldArea - 2, self.foldArea - 1,
                    3, 3)

            block = block.next()# block = next(block)

        painter.end()
        super(SidebarWidget, self).paintEvent(event)
Esempio n. 11
0
    def paintEvent(self, event):
        page_bottom = self.edit.viewport().height()
        font_metrics = QFontMetrics(self.edit.document().defaultFont())
        current_block = self.edit.document().findBlock(
            self.edit.textCursor().position())
        pattern = self.pat if self.edit.lang == "python" else self.patNotPython

        painter = QPainter(self)
        background = resources.CUSTOM_SCHEME.get(
            'sidebar-background', resources.COLOR_SCHEME['sidebar-background'])
        foreground = resources.CUSTOM_SCHEME.get(
            'sidebar-foreground', resources.COLOR_SCHEME['sidebar-foreground'])
        background_selected = resources.CUSTOM_SCHEME.get(
            'sidebar-selected-background',
            resources.COLOR_SCHEME['sidebar-selected-background'])
        foreground_selected = resources.CUSTOM_SCHEME.get(
            'sidebar-selected-foreground',
            resources.COLOR_SCHEME['sidebar-selected-foreground'])
        painter.fillRect(self.rect(), QColor(background))

        block = self.edit.firstVisibleBlock()
        viewport_offset = self.edit.contentOffset()
        line_count = block.blockNumber()
        painter.setFont(self.edit.document().defaultFont())

        xofs = self.width() - self.foldArea
        painter.fillRect(
            xofs, 0, self.foldArea, self.height(),
            QColor(
                resources.CUSTOM_SCHEME.get(
                    'fold-area', resources.COLOR_SCHEME['fold-area'])))

        while block.isValid():
            line_count += 1
            # The top left position of the block in the document
            position = self.edit.blockBoundingGeometry(block).topLeft() + \
                viewport_offset
            # Check if the position of the block is outside of the visible area
            if position.y() > page_bottom:
                break

            # Set the Painter Pen depending on special lines
            painter.setPen(QColor(foreground))
            error = False
            checkers = self._neditable.sorted_checkers
            for items in checkers:
                checker, color, _ = items
                if (line_count - 1) in checker.checks:
                    painter.setPen(QColor(color))
                    font = painter.font()
                    font.setItalic(True)
                    font.setUnderline(True)
                    painter.setFont(font)
                    error = True
                    break

            # We want the line number for the selected line to be bold.
            bold = False
            if block == current_block:
                painter.fillRect(
                    0,
                    round(position.y()) + font_metrics.descent(), self.width(),
                    font_metrics.ascent() + font_metrics.descent(),
                    QColor(background_selected))

                bold = True
                font = painter.font()
                font.setBold(True)
                if not error:
                    painter.setPen(QColor(foreground_selected))
                painter.setFont(font)

            # Draw the line number right justified at the y position of the
            # line. 3 is a magic padding number. drawText(x, y, text).
            if block.isVisible():
                painter.drawText(
                    self.width() - self.foldArea -
                    font_metrics.width(str(line_count)) - 3,
                    round(position.y()) + font_metrics.ascent() +
                    font_metrics.descent() - 1, str(line_count))

            # Remove the bold style if it was set previously.
            if bold:
                font = painter.font()
                font.setBold(False)
                painter.setFont(font)
            if error:
                font = painter.font()
                font.setItalic(False)
                font.setUnderline(False)
                painter.setFont(font)

            block = block.next()

        self.highest_line = line_count

        #Code Folding
        if self.foldArea != self.rightArrowIcon.width():
            polygon = QPolygonF()

            self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea)
            self.rightArrowIcon.fill(Qt.transparent)
            self.downArrowIcon = QPixmap(self.foldArea, self.foldArea)
            self.downArrowIcon.fill(Qt.transparent)

            polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25))
            polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75))
            polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5))
            iconPainter = QPainter(self.rightArrowIcon)
            iconPainter.setRenderHint(QPainter.Antialiasing)
            iconPainter.setPen(Qt.NoPen)
            iconPainter.setBrush(
                QColor(
                    resources.CUSTOM_SCHEME.get(
                        'fold-arrow', resources.COLOR_SCHEME['fold-arrow'])))
            iconPainter.drawPolygon(polygon)

            polygon.clear()
            polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4))
            polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4))
            polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8))
            iconPainter = QPainter(self.downArrowIcon)
            iconPainter.setRenderHint(QPainter.Antialiasing)
            iconPainter.setPen(Qt.NoPen)
            iconPainter.setBrush(
                QColor(
                    resources.CUSTOM_SCHEME.get(
                        'fold-arrow', resources.COLOR_SCHEME['fold-arrow'])))
            iconPainter.drawPolygon(polygon)

            self.calculate_docstring_block_fold()

        block = self.edit.firstVisibleBlock()
        while block.isValid():
            position = self.edit.blockBoundingGeometry(
                block).topLeft() + viewport_offset
            #Check if the position of the block is outside of the visible area
            if position.y() > page_bottom:
                break

            if pattern.match(block.text()) and block.isVisible():
                can_fold = True
                if self.patComment.match(block.text()) and \
                   (block.blockNumber() in self._endDocstringBlocks):
                    can_fold = False

                if can_fold:
                    if block.blockNumber() in self.foldedBlocks:
                        painter.drawPixmap(xofs, round(position.y()),
                                           self.rightArrowIcon)
                    else:
                        painter.drawPixmap(xofs, round(position.y()),
                                           self.downArrowIcon)
            #Add Bookmarks and Breakpoint
            if block.blockNumber() in self.breakpoints:
                linear_gradient = QLinearGradient(
                    xofs, round(position.y()), xofs + self.foldArea,
                    round(position.y()) + self.foldArea)
                linear_gradient.setColorAt(0, QColor(255, 11, 11))
                linear_gradient.setColorAt(1, QColor(147, 9, 9))
                painter.setRenderHints(QPainter.Antialiasing, True)
                painter.setPen(Qt.NoPen)
                painter.setBrush(QBrush(linear_gradient))
                painter.drawEllipse(xofs + 1,
                                    round(position.y()) + 6, self.foldArea - 1,
                                    self.foldArea - 1)
            elif block.blockNumber() in self.bookmarks:
                linear_gradient = QLinearGradient(
                    xofs, round(position.y()), xofs + self.foldArea,
                    round(position.y()) + self.foldArea)
                linear_gradient.setColorAt(0, QColor(13, 62, 243))
                linear_gradient.setColorAt(1, QColor(5, 27, 106))
                painter.setRenderHints(QPainter.Antialiasing, True)
                painter.setPen(Qt.NoPen)
                painter.setBrush(QBrush(linear_gradient))
                painter.drawRoundedRect(xofs + 1,
                                        round(position.y()) + 6,
                                        self.foldArea - 2, self.foldArea - 1,
                                        3, 3)

            block = block.next()

        painter.end()
        super(SidebarWidget, self).paintEvent(event)
Esempio n. 12
0
class Arrow(QGraphicsItemGroup):
    def __init__(self, start):
        super().__init__()
        self.fromItem = start
        self.startPoint = None
        self.toItem = None
        self.endPoint = None
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.color = Qt.black
        self.pen = QPen(self.color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        self.arrowHead = QPolygonF()

        self.lines = []
        self.qLines = []

        #experimental
        self.setFlag(QGraphicsItem.ItemIsMovable)

    """
	We need to reimplement this function because the arrow is larger 
	than the bounding rectangle of the QGraphicsLineItem. The graphics
	scene uses the bounding rectangle to know which regions of the scene to update
	"""

    def boundingRect(self):
        extra = (self.pen.width() + 20) / 2.0

        #rect = QRectF(self.line().p1(), QSizeF(self.line().p2().x() - self.line().p1().x(),
        #                      self.line().p2().y() - self.line().p1().y()))
        rect = self.calcRect()
        #return self.arrowHead.boundingRect()
        return rect.normalized().adjusted(-extra, -extra, extra, extra)

    """
	The shape function returns a QPainterPath that is the exact shape
	of the item. The QGraphicsLineItem::shape() returns a path with a
	line drawn with the current pen, so we only need to add the arrow
	head. This function is used to check for collisions and selections
	with the mouse.
	"""

    def shape(self):
        #path = super().shape()
        path = QPainterPath()
        #path.addRect(self.calcRect())
        path.addPolygon(self.arrowHead)

        return path

    #redraw, due to moving an object
    def recalcUpdate(self):
        if self.fromItem is None or self.toItem is None:
            return
        coordinates = QLineF(
            self.fromItem.getLinePoint(self.toItem.center())[1],
            self.toItem.getLinePoint(self.fromItem.center())[1])
        #self.setLine(coordinates)

    """
	is called, when one of the items is moved.
	it recalculates the lines
	"""

    def move(self):
        self.startPoint = GeoHelper.movePoint(
            self.posFromItem,
            self.fromItem.getPositionalRect().topLeft(), self.startPoint)
        self.endPoint = GeoHelper.movePoint(
            self.posToItem,
            self.toItem.getPositionalRect().topLeft(), self.endPoint)
        g = Geometry()
        self.lines = g.rectToRect(self.startPoint,
                                  self.fromItem.getPositionalRect(),
                                  self.endPoint,
                                  self.toItem.getPositionalRect())
        self.posToItem = self.toItem.getPositionalRect().topLeft()
        self.posFromItem = self.fromItem.getPositionalRect().topLeft()

        self.update(self.boundingRect())

    def drawLine(self, point, item):
        if item is not None:
            self.setItem2(item, point)
        else:
            self.setPoint2(point)
        self.update(self.boundingRect())
        #trigger paint to update/ redraw
        #self.setLine(self.lines[-1])
        #super().update(self.boundingRect())

    def setPoint2(self, point):
        if self.startPoint is None:
            s1, self.startPoint = self.fromItem.getNearestPoint(point)
        g = Geometry()
        self.lines = g.rectToPoint(self.startPoint,
                                   self.fromItem.getPositionalRect(), point)

    """
	saves second rectangle/Item and end point of a connection

	params
	------
	end: RoundedRect
	     second rectangle/ toItem
	pos: QPointF
	     position of mouse
	"""

    def setItem2(self, end, pos):
        #save endPoint
        s2, self.endPoint = end.getNearestPoint(pos)
        #save endItem
        self.toItem = end
        #save position (for moving)
        self.posToItem = self.toItem.getPositionalRect().topLeft()
        self.posFromItem = self.fromItem.getPositionalRect().topLeft()
        g = Geometry()
        self.lines = g.rectToRect(self.startPoint,
                                  self.fromItem.getPositionalRect(),
                                  self.endPoint, end.getPositionalRect())
        print("a:", self.lines)

    def connect(self, end):
        self.toItem = end
        self.toItem.addInput(self)
        self.fromItem.addOutput(self)

    def calcRect(self):
        minX = self.lines[0].p1().x()
        minY = self.lines[0].p1().y()
        maxX = self.lines[0].p1().x()
        maxY = self.lines[0].p1().y()

        for l in self.lines:
            minX = min(minX, l.p1().x())
            minY = min(minY, l.p1().y())
            maxX = max(maxX, l.p1().x())
            maxY = max(maxY, l.p1().y())
            minX = min(minX, l.p2().x())
            minY = min(minY, l.p2().y())
            maxX = max(maxX, l.p2().x())
            maxY = max(maxY, l.p2().y())

        return QRectF(QPointF(minX, minY), QPointF(maxX, maxY))

    def addOrAppend(self, i, line):
        if len(self.lines) > i:
            self.lines[i] = line
        else:
            self.lines.append(line)

    def resetLines(self, pen):
        for l in self.qLines:
            self.scene().removeItem(l)
        self.qLines = []
        for l in self.lines:
            #line = QGraphicsLineItem(l, self)
            line = LineItem(l, self)
            line.setPen(pen)
            #line.setFlag(QGraphicsItem.ItemIsSelectable)
            self.qLines.append(line)

    def paint(self, painter, option, widget=None):
        arrowSize = 10

        if self.isSelected():
            pen = QPen(Qt.red, 1)
            color = Qt.red
        else:
            pen = self.pen
            color = self.color
        painter.setPen(pen)
        painter.setBrush(color)
        #calculate line
        #coordinates = QLineF(self.fromItem.getLinePoint(self.toItem.center()),
        #	self.toItem.getLinePoint(self.fromItem.center()))
        #self.setLine(coordinates)

        #calculate points of arrow
        line = self.lines[-1]
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi * 2) - angle

        p1 = line.p2() - QPointF(
            math.sin(angle + math.pi / 3) * arrowSize,
            math.cos(angle + math.pi / 3) * arrowSize)
        p2 = line.p2() - QPointF(
            math.sin(angle + math.pi - math.pi / 3) * arrowSize,
            math.cos(angle + math.pi - math.pi / 3) * arrowSize)

        self.arrowHead.clear()
        self.arrowHead.append(line.p2())
        self.arrowHead.append(p1)
        self.arrowHead.append(p2)
        painter.drawPolygon(self.arrowHead)
        self.resetLines(pen)
Esempio n. 13
0
class Arrow(QGraphicsLineItem):
    def __init__(
        self,
        start_item: DiagramItem,
        end_item: DiagramItem,
        parent: QGraphicsItem = None,
        scene: QGraphicsScene = None,
    ):
        super(Arrow, self).__init__()

        self.start_item = start_item
        self.end_item = end_item
        self.arrow_head = QPolygonF()

        # Could be used later to support coloring.
        self.color = Qt.black

        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setPen(
            QPen(self.color, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

    def get_start_item(self) -> DiagramItem:
        return self.start_item

    def get_end_item(self) -> DiagramItem:
        return self.end_item

    def boundingRect(self) -> QRectF:
        extra = (self.pen().width() + 20) / 2.0
        p1 = self.line().p1()
        p2 = self.line().p2()
        return (QRectF(p1, QSizeF(p2.x() - p1.x(),
                                  p2.y() - p1.y())).normalized().adjusted(
                                      -extra, -extra, extra, extra))

    def shape(self):
        path = super(Arrow, self).shape()
        path.addPolygon(self.arrow_head)
        return path

    def updatePosition(self):
        line = QLineF(self.mapFromItem(self.start_item, 0, 0),
                      self.mapFromItem(self.end_item, 0, 0))
        self.setLine(line)

    def paint(self, painter, option, widget=None):
        if self.start_item.collidesWithItem(self.end_item):
            return

        start_item = self.start_item
        end_item = self.end_item
        color = self.color
        pen = self.pen()
        pen.setColor(color)
        arrow_size = 10.0
        painter.setPen(pen)
        painter.setBrush(color)

        center_line = QLineF(start_item.pos(), end_item.pos())
        end_polygon = end_item.polygon
        p1 = end_polygon.first() + end_item.pos()

        intersect_point = QPointF()
        for i in end_polygon:
            p2 = i + end_item.pos()
            poly_line = QLineF(p1, p2)
            intersect_type = poly_line.intersect(center_line, intersect_point)
            if intersect_type == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersect_point, start_item.pos()))
        line = self.line()

        angle = math.acos(line.dx() / max(1, line.length()))
        if line.dy() >= 0:
            angle = (math.pi * 2.0) - angle

        arrow_p1 = (line.p1() + QPointF(
            math.sin(angle + math.pi / 3.0) * arrow_size,
            math.cos(angle + math.pi / 3.0) * arrow_size,
        ))

        arrow_p2 = (line.p1() + QPointF(
            math.sin(angle + math.pi - math.pi / 3.0) * arrow_size,
            math.cos(angle + math.pi - math.pi / 3.0) * arrow_size,
        ))

        self.arrow_head.clear()
        for point in [line.p1(), arrow_p1, arrow_p2]:
            self.arrow_head.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrow_head)

        if self.isSelected():
            painter.setPen(QPen(color, 1, Qt.DashLine))
            line = QLineF(line)
            line.translate(0, 4.0)
            painter.drawLine(line)
            line.translate(0, -8.0)
            painter.drawLine(line)
Esempio n. 14
0
class Link(QGraphicsLineItem):
    """!
    Link between Ports
    """
    def __init__(self, from_port, to_port):
        """!
        @brief Link between two Ports (of different Nodes)
        @param from_port <OutputPort>: origin port
        @param to_port <InputPort>: destination port
        """
        super().__init__()
        self.setFlag(QGraphicsItem.ItemIsSelectable)

        self.head = None
        self.tail = None

        self.selection_offset = 8
        self.arrow_size = 10
        self.selection_polygon = None
        self.from_port = from_port
        self.to_port = to_port
        self.arrow_head = QPolygonF()
        self.update_nodes()

        self.pen = QPen(Qt.black, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        self.dashed_pen = QPen(Qt.black, 1, Qt.DashLine)
        self.brush = QBrush(Qt.black)

    def save(self):
        return '|'.join(
            map(str, [
                self.from_port.parentItem().index(),
                self.from_port.index(),
                self.to_port.parentItem().index(),
                self.to_port.index()
            ]))

    def update_polygon(self):
        angle = self.line().angle() * math.pi / 180
        dx = self.selection_offset * math.sin(angle)
        dy = self.selection_offset * math.cos(angle)
        offset1 = QPointF(dx, dy)
        offset2 = QPointF(-dx, -dy)
        if self.head is None and self.tail is None:
            self.selection_polygon = QPolygonF([
                self.line().p1() + offset1,
                self.line().p1() + offset2,
                self.line().p2() + offset2,
                self.line().p2() + offset1
            ])
        elif self.tail is None:
            head_angle = self.head.angle() * math.pi / 180
            head_dx = self.selection_offset * math.sin(head_angle)
            head_dy = self.selection_offset * math.cos(head_angle)
            head_offset1 = QPointF(head_dx, head_dy)
            head_offset2 = QPointF(-head_dx, -head_dy)
            self.selection_polygon = QPolygonF([
                self.line().p1() + offset1,
                self.head.p1() + head_offset1,
                self.head.p1() + head_offset2,
                self.line().p1() + offset2,
                self.line().p2() + offset2,
                self.line().p2() + offset1
            ])
        elif self.head is None:
            tail_angle = self.tail.angle() * math.pi / 180
            tail_dx = self.selection_offset * math.sin(tail_angle)
            tail_dy = self.selection_offset * math.cos(tail_angle)
            tail_offset1 = QPointF(tail_dx, tail_dy)
            tail_offset2 = QPointF(-tail_dx, -tail_dy)
            self.selection_polygon = QPolygonF([
                self.line().p1() + offset1,
                self.line().p1() + offset2,
                self.line().p2() + offset2,
                self.tail.p2() + tail_offset2,
                self.tail.p2() + tail_offset1,
                self.line().p2() + offset1
            ])
        else:
            head_angle = self.head.angle() * math.pi / 180
            head_dx = self.selection_offset * math.sin(head_angle)
            head_dy = self.selection_offset * math.cos(head_angle)
            head_offset1 = QPointF(head_dx, head_dy)
            head_offset2 = QPointF(-head_dx, -head_dy)
            tail_angle = self.tail.angle() * math.pi / 180
            tail_dx = self.selection_offset * math.sin(tail_angle)
            tail_dy = self.selection_offset * math.cos(tail_angle)
            tail_offset1 = QPointF(tail_dx, tail_dy)
            tail_offset2 = QPointF(-tail_dx, -tail_dy)
            self.selection_polygon = QPolygonF([
                self.line().p1() + offset1,
                self.head.p1() + head_offset1,
                self.head.p1() + head_offset2,
                self.line().p1() + offset2,
                self.line().p2() + offset2,
                self.tail.p2() + tail_offset2,
                self.tail.p2() + tail_offset1,
                self.line().p2() + offset1
            ])

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

    def shape(self):
        path = QPainterPath()
        path.addPolygon(self.selection_polygon)
        return path

    def paint(self, painter, options, widget=None):
        painter.setPen(self.pen)
        if self.head is not None:
            painter.drawLine(self.head)
        if self.tail is not None:
            painter.drawLine(self.tail)
        painter.drawLine(self.line())
        if self.isSelected():
            painter.setPen(self.dashed_pen)
            painter.drawPolygon(self.selection_polygon)

        # draw the arrow tip
        if self.tail is not None:
            tail_line = self.tail
        else:
            tail_line = self.line()
        intersection_point = QPointF(0, 0)
        for line in self.to_port.lines():
            line = QLineF(self.mapFromScene(line.p1()),
                          self.mapFromScene(line.p2()))
            intersection_type = tail_line.intersect(line, intersection_point)
            if intersection_type == QLineF.BoundedIntersection:
                break
        angle = math.acos(tail_line.dx() / tail_line.length())
        if tail_line.dy() >= 0:
            angle = (math.pi * 2) - angle

        arrow_p1 = intersection_point - QPointF(
            math.sin(angle + math.pi / 3) * self.arrow_size,
            math.cos(angle + math.pi / 3) * self.arrow_size)
        arrow_p2 = intersection_point - QPointF(
            math.sin(angle + math.pi - math.pi / 3) * self.arrow_size,
            math.cos(angle + math.pi - math.pi / 3) * self.arrow_size)
        self.arrow_head.clear()
        for p in [intersection_point, arrow_p1, arrow_p2]:
            self.arrow_head.append(p)
        path = QPainterPath()
        path.addPolygon(self.arrow_head)
        painter.fillPath(path, self.brush)

    def update_nodes(self):
        p1 = self.from_port.rect().center()
        p2 = self.to_port.rect().center()
        p1 = self.from_port.parentItem().mapToScene(p1)
        p2 = self.to_port.parentItem().mapToScene(p2)

        line = QLineF(p1, p2)
        self.setLine(line)
        self.update_polygon()

        box1 = self.from_port.parentItem().mapRectToScene(
            self.from_port.parentItem().box.rect())
        if box1.intersects(self.boundingRect()):
            p3 = box1.bottomRight() + QPointF(0, Port.WIDTH / 2)
            self.head = QLineF(p1, p3)
            line = QLineF(p3, p2)
        else:
            self.head = None
        box2 = self.to_port.parentItem().mapRectToScene(
            self.to_port.parentItem().box.rect())
        if box2.intersects(self.boundingRect()):
            p4 = box2.topLeft() + QPointF(-Port.WIDTH / 2, 0)
            self.tail = QLineF(p4, p2)
            line = QLineF(line.p1(), p4)
        else:
            self.tail = None

        self.setLine(line)
        self.update_polygon()
        self.update()

    def remove(self):
        self.from_port.disconnect(self.to_port)
        self.to_port.disconnect()
        self.from_port.parentItem().remove_link(self)
        self.to_port.parentItem().remove_link(self)
        self.to_port.parentItem().reconfigure()
Esempio n. 15
0
class MovableArrow(QGraphicsLineItem):
    def __init__(self, parent=None):
        super(MovableArrow, self).__init__(parent)
        self.setZValue(1000)

        self.arrowHead = QPolygonF()
        self.begin = np.array([0.0, 0.0])
        self.end = np.array([10.0, 10.0])

        self.myColor = Qt.black
        self.setPen(QPen(self.myColor, 5))
        self.arrowSize = 5
        self.setOpacity(0.4)

        self.isMousePressed = False
        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsFocusable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemSendsGeometryChanges)

        self.angleFixedFlag = False
        self.objectName = None

    def boundingRect(self):
        extra = (self.pen().width() + 20) / 2.0
        size = QSizeF(1.3 * (self.line().p1().x() - self.line().p2().x()),
                      1.3 * (self.line().p1().y() - self.line().p2().y()))

        return QRectF(self.line().p2(),
                      size).normalized().adjusted(-extra, -extra, extra, extra)

    def shape(self):
        path = super(MovableArrow, self).shape()
        path.addPolygon(self.arrowHead)
        return path

    def setColor(self, colorArray):
        self.myColor = QColor(*colorArray)

    def updatePosition(self):
        line = QLineF(QPointF(*self.end), QPointF(*self.begin))
        self.setLine(line)
        self.shape()

    def paint(self, painter, option, widget=None):
        self.updatePosition()

        myPen = self.pen()
        myPen.setColor(self.myColor)
        painter.setPen(myPen)
        # painter.setBrush(self.myColor)

        try:
            angle = np.arccos(self.line().dx() / self.line().length())
        except ZeroDivisionError:
            angle = 0.0
        if self.line().dy() >= 0:
            angle = (np.pi * 2) - angle

        l = self.line().length() * 0.1
        arrowP0 = self.line().p1() - QPointF(self.line().dx() / l,
                                             self.line().dy() / l)

        arrowP1 = self.line().p1() + QPointF(
            np.sin(angle + np.pi / 6) * self.arrowSize,
            np.cos(angle + np.pi / 6) * self.arrowSize)
        arrowP2 = self.line().p1() + QPointF(
            np.sin(angle + np.pi - np.pi / 6) * self.arrowSize,
            np.cos(angle + np.pi - np.pi / 6) * self.arrowSize)

        self.arrowHead.clear()
        self.arrowHead.append(arrowP0)
        self.arrowHead.append(arrowP1)
        self.arrowHead.append(arrowP2)

        # painter.drawConvexPolygon(self.arrowHead)
        arrow = QPainterPath()
        arrow.addPolygon(self.arrowHead)
        painter.fillPath(arrow, QBrush(self.myColor))

        painter.drawLine(self.line())

        self.shape()

    def mousePressEvent(self, event):
        self.isMousePressed = True
        self.mousePressedPos = event.scenePos()
        self.end_old = self.end.copy()
        super(MovableArrow, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        mouseCursorPos = event.scenePos()
        #mouseCursorPos = event.Pos()
        if self.isMousePressed:
            x = mouseCursorPos.x() - self.mousePressedPos.x()
            y = mouseCursorPos.y() - self.mousePressedPos.y()
            delta = np.array([x, y])
            # angle = ang(self.begin, self.end+delta)
            if self.angleFixedFlag == False:
                self.end[:] = self.end_old + delta
            else:
                T = self.end_old - self.begin
                delta = delta
                self.end[:] = self.begin + (
                    (T) / np.linalg.norm(T)) * np.linalg.norm(delta)

            self.updatePosition()
        #super(MovableArrow, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self.isMousePressed = False
        super(MovableArrow, self).mouseReleaseEvent(event)

    def getVector(self):
        return self.end - self.begin

    def setObjectName(self, name):
        self.objectName = name

    def objectName(self):
        return self.objectName
Esempio n. 16
0
class Edge(QGraphicsLineItem):
    """
    Implements an Edge to two nodes
    """

    def __init__(self, start, dst, offset, color=Qt.black):
        """
        Constructor for a conjunction.
        It generates all necessary variables and calls the draw function
        It adds also the parent arrow from the source to the conjunction rectangle

        :param start: Starting object of the arrow
        :param dst: End object of the arrow
        :param offset: left/right offset for the starting arrow
        :param color: Color of the arrow
        """
        super().__init__()

        self.arrowHead = QPolygonF()

        self.start = start
        self.dst = dst

        self.offset = offset

        self.setFlag(QGraphicsItem.ItemIsSelectable, True)

        self.setPen(QPen(color, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

        self.updatePosition()

    def boundingRect(self):
        """
        New calculation of the bounding rect, because the arrow is not only a line

        :return: new bounding rectangle
        """
        extra = (self.pen().width() + 20) / 2.0
        return QRectF(self.line().p1(), QSizeF(self.line().p2().x() - self.line().p1().x(),
                                               self.line().p2().y() - self.line().p1().y())).normalized().adjusted(
            -extra, -extra, extra, extra)

    def shape(self):
        """
        Calculation of the shape of the arrow

        :return: shape of the arrow
        """
        path = QGraphicsLineItem.shape(self)
        path.addPolygon(self.arrowHead)
        return path

    def updatePosition(self):
        """
        Updates the position of the arrow
        """
        line = QLineF(self.mapFromItem(self.start, 0, 0), self.mapFromItem(self.dst, 0, 0))
        self.setLine(line)

    def paint(self, painter, options, widget=None):
        """
        Painter implementation for the arrow.
        First it draws the line and then the triangle on the end

        :param painter: The painter, which draws the node
        :param options: options for the paint job
        :param widget: widget of the Item
        """

        if self.start.collidesWithItem(self.dst):
            return

        myPen = self.pen()
        arrowSize = 10
        painter.setPen(myPen)
        painter.setBrush(myPen.color())
        """
        Calculation for the line
        """
        centerLine = QLineF(QPointF(self.start.x() + self.start.boundingRect().center().x() + self.offset,
                                    self.start.y() + self.start.boundingRect().bottom()),
                            QPointF(self.dst.x() + self.dst.boundingRect().center().x(), self.dst.y()))
        endPolygon = self.dst.mapFromItem(self.dst, self.dst.boundingRect())
        p1 = endPolygon.first() + self.dst.pos()
        p2 = None
        intersectPoint = QPointF()

        for i in endPolygon:
            p2 = i + self.dst.pos()

            polyLine = QLineF(p1, p2)

            intersectType = polyLine.intersect(centerLine, intersectPoint)
            if intersectType == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersectPoint,
                            QPointF(self.start.x() + self.start.boundingRect().center().x() + self.offset,
                                    self.start.y() + self.start.boundingRect().bottom())))

        """
        Calculation for the arrow
        It calculates an left and an right part of the arrow
        """
        angle = math.atan2(-self.line().dy(), self.line().dx())
        arrowP1 = self.line().p1() + QPointF(math.sin(angle + math.pi / 3) * arrowSize,
                                             math.cos(angle + math.pi / 3) * arrowSize)
        arrowP2 = self.line().p1() + QPointF(math.sin(angle + math.pi - math.pi / 3) * arrowSize,
                                             math.cos(angle + math.pi - math.pi / 3) * arrowSize)

        self.arrowHead.clear()
        self.arrowHead << self.line().p1() << arrowP1 << arrowP2

        painter.drawLine(self.line())
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(Qt.black, 1, Qt.DashLine))
            myLine = self.line()
            myLine.translate(0, 4.0)
            painter.drawLine(myLine)
            myLine.translate(0, -8.0)
            painter.drawLine(myLine)

    def selectChildren(self):
        """
        Select all children of the destination
        """
        self.dst.selectChildren()