示例#1
0
 def renderImage(self, remove_useless_background=False):
     if not self.Image:
         return
     paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32)
     paintedImage.fill(Qt.transparent)
     painter = QPainter(paintedImage)
     if self.cropPolygon:
         painterPath = QPainterPath()
         painterPath.addPolygon(self.cropPolygon)
         painter.setClipPath(painterPath)
     painter.drawImage(QPoint(), self.Image)
     # draw polygon
     pen = QPen(self.PolygonEdgeColor, 5)
     painter.setPen(pen)
     if len(self.polygonList):
         for polygon in self.polygonList:
             # pp = QPolygonF([QPointF(point[0], point[1]) for point in polygon['geo']])
             if polygon['selected']:
                 painter.setBrush(self.PolygonSelectedColor)
             else:
                 painter.setBrush(self.PolygonColor)
             painter.drawPolygon(polygon['geo'])
     painter.end()
     if remove_useless_background and self.cropPolygon:
         return paintedImage.copy(painterPath.boundingRect().toRect())
     else:
         return paintedImage
示例#2
0
    def mouseMoveEvent(self, event):
        super(CBlueprintView, self).mouseMoveEvent(event)
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        pos = event.pos()
        if self.m_StartPos:
            offsetX, offsetY = pos.x() - self.m_StartPos.x(), pos.y(
            ) - self.m_StartPos.y()
            offsetX /= self.m_Scale
            offsetY /= self.m_Scale
            self.translate(offsetX, offsetY)
            self.m_StartPos = pos
            self.m_IsHasMove = True

        if self.m_SelectPos:
            rect = QRect(min(self.m_SelectPos.x(), pos.x()),
                         min(self.m_SelectPos.y(), pos.y()),
                         abs(self.m_SelectPos.x() - pos.x()),
                         abs(self.m_SelectPos.y() - pos.y()))
            path = QPainterPath()
            path.addPolygon(self.mapToScene(rect))
            path.closeSubpath()
            self.m_Scene.RubberBandSelecNodeUI(path,
                                               self.rubberBandSelectionMode(),
                                               self.viewportTransform())
            self.m_RubberBand.setGeometry(rect)
示例#3
0
    def calc_path(self):
        path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1]))  # 起点
        path.lineTo(QPointF(self.pos_dst[0], self.pos_dst[1]))  # 终点
        if self.directed:
            # 画箭头
            self.line = QLineF(QPointF(self.pos_src[0], self.pos_src[1]), QPointF(self.pos_dst[0], self.pos_dst[1]))
            if self.flag == 0:
                self.line.setLength(self.line.length() - 20)
            else:
                self.line.setLength(self.line.length() - self.edge_wrap.end_item.r)
            v = self.line.unitVector()
            v.setLength(20)
            v.translate(QPointF(self.line.dx(), self.line.dy()))

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

            p1 = v.p2()
            p2 = n.p2()
            p3 = n2.p2()
            # 方法2
            arrow = QPolygonF([p1, p2, p3, p1])
            path.addPolygon(arrow)
        # path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1]))
        # path.lineTo(self.pos_dst[0], self.pos_dst[1])
        return path
示例#4
0
    def shape(self, object):
        path = QPainterPath()
        if (not object.cell().isEmpty()):
            path.addRect(self.boundingRect(object))
        else:
            x = object.shape()
            if x == MapObject.Rectangle:
                bounds = object.bounds()
                if (bounds.isNull()):
                    path.addEllipse(bounds.topLeft(), 20, 20)
                else:
                    path.addRoundedRect(bounds, 10, 10)
            elif x == MapObject.Polygon or x == MapObject.Polyline:
                pos = object.position()
                polygon = object.polygon().translated(pos)
                screenPolygon = self.pixelToScreenCoords_(polygon)
                if (object.shape() == MapObject.Polygon):
                    path.addPolygon(screenPolygon)
                else:
                    for i in range(1, screenPolygon.size()):
                        path.addPolygon(
                            self.lineToPolygon(screenPolygon[i - 1],
                                               screenPolygon[i]))

                    path.setFillRule(Qt.WindingFill)
            elif x == MapObject.Ellipse:
                bounds = object.bounds()
                if (bounds.isNull()):
                    path.addEllipse(bounds.topLeft(), 20, 20)
                else:
                    path.addEllipse(bounds)

        return path
	def __init__(self, parentItem, segments, colour):
		QGraphicsItem.__init__(self, parent=parentItem)
		self.colour_name = colour
		self.shape = QPainterPath()
		self.labels = QGraphicsItemGroup(self)
		self.bbox = QRectF(0, 0, 0, 0)
		for (p1, p2), label in segments:
			lvect = QVector2D(p2 - p1)
			lpath = QPainterPath()
			m = TWY_line_margin
			l = lvect.length()
			plst = [QPointF(-m, 0), QPointF(-m/3, -m), QPointF(l + m/3, -m), QPointF(l + m, 0), QPointF(l + m/3, m), QPointF(-m/3, m)]
			lpath.addPolygon(QPolygonF(plst))
			lrot = QTransform()
			lrot.rotateRadians(atan2(lvect.y(), lvect.x()))
			lpath = lrot.map(lpath)
			lpath.translate(p1)
			self.shape.addPath(lpath)
			rect = QRectF(p1, p2).normalized()
			if label != None:
				self.labels.addToGroup(TaxiwayLabelItem(label, rect.center(), self))
			self.bbox |= rect
		self.shape.setFillRule(Qt.WindingFill)
		self.mouse_highlight = False
		self.labels.setVisible(False)
示例#6
0
    def drawPolygonOnVideo(values, painter, surface, gt):
        ''' Draw Polygons on Video '''
        poly = []
        for pt in values:
            if hasElevationModel():
                pt = GetLine3DIntersectionWithPlane(
                    GetSensor(), pt, GetFrameCenter()[2])
            scr_x, scr_y = vut.GetInverseMatrix(
                pt[1], pt[0], gt, surface)
            center = QPoint(scr_x, scr_y)
            poly.append(center)

        poly.append(poly[0])

        radius = 3
        polygon = QPolygonF(poly)
        pen = QPen()
        pen.setColor(Qt.green)
        pen.setWidth(radius)
        pen.setCapStyle(Qt.RoundCap)
        pen.setJoinStyle(Qt.RoundJoin)

        brush = QBrush()
        brush.setColor(QColor(176, 255, 128, 28))
        brush.setStyle(Qt.SolidPattern)

        path = QPainterPath()
        path.addPolygon(polygon)

        painter.setPen(pen)
        painter.drawPolygon(polygon)
        painter.fillPath(path, brush)
        return
示例#7
0
    def paintStripe(self, st, p, coord, color):
        # left right
        if st == 0:
            left1 = QPoint(coord[0],
                           coord[1] + self.grid_size // 2 - self.radius)
            left2 = QPoint(coord[0],
                           coord[1] + self.grid_size // 2 + self.radius)
            right1 = QPoint(left1.x() + self.grid_size, left1.y())
            right2 = QPoint(left2.x() + self.grid_size, left2.y())
            poly = QPolygonF([left1, right1, right2, left2])
        # top to bottom
        elif st == 1:
            top1 = QPoint(coord[0] + self.grid_size // 2 - self.radius,
                          coord[1])
            top2 = QPoint(coord[0] + self.grid_size // 2 + self.radius,
                          coord[1])
            bot1 = QPoint(top1.x(), top1.y() + self.grid_size)
            bot2 = QPoint(top2.x(), top2.y() + self.grid_size)
            poly = QPolygonF([top1, top2, bot2, bot1])

        path = QPainterPath()
        path.addPolygon(poly)
        p.drawPolygon(poly)

        brush = QBrush()
        brush.setColor(color)
        brush.setStyle(Qt.SolidPattern)
        p.fillPath(path, brush)
示例#8
0
    def shape(self, object):
        path = QPainterPath()
        if (not object.cell().isEmpty()):
            path.addRect(self.boundingRect(object))
        else:
            x = object.shape()
            if x==MapObject.Rectangle:
                bounds = object.bounds()
                if (bounds.isNull()):
                    path.addEllipse(bounds.topLeft(), 20, 20)
                else:
                    path.addRoundedRect(bounds, 10, 10)
            elif x==MapObject.Polygon or x==MapObject.Polyline:
                pos = object.position()
                polygon = object.polygon().translated(pos)
                screenPolygon = self.pixelToScreenCoords_(polygon)
                if (object.shape() == MapObject.Polygon):
                    path.addPolygon(screenPolygon)
                else:
                    for i in range(1, screenPolygon.size()):
                        path.addPolygon(self.lineToPolygon(screenPolygon[i - 1],
                                                      screenPolygon[i]))

                    path.setFillRule(Qt.WindingFill)
            elif x==MapObject.Ellipse:
                bounds = object.bounds()
                if (bounds.isNull()):
                    path.addEllipse(bounds.topLeft(), 20, 20)
                else:
                    path.addEllipse(bounds)

        return path
示例#9
0
    def paintEvent(self, event):
        if self.display_status:
            super().paintEvent(event)
            painter = QPainter(self)
            painter_path = QPainterPath()

            qt_pen_1 = QPen(Qt.red, 2, Qt.SolidLine)
            qt_pen_2 = QPen(Qt.green, 10, Qt.SolidLine)
            qt_pen_3 = QPen(Qt.red, 2, Qt.DotLine)

            painter.setPen(qt_pen_1)
            painter.drawPolygon(QPolygon(self.roi_rect), Qt.WindingFill)

            painter_path.addPolygon(QPolygonF(self.roi_rect))
            painter_path.closeSubpath()

            # qt_brush = QBrush(Qt.green)
            qt_brush = QBrush(QColor(0, 255, 0, 64))

            painter.setBrush(qt_brush)
            painter.drawPath(painter_path)

            # painter.drawPoint(self.tmp_center_pt)
            painter.setPen(qt_pen_3)
            painter.drawLine(self.roi_rect[0], self.roi_rect[2])
            painter.drawLine(self.roi_rect[1], self.roi_rect[3])

            painter.setPen(qt_pen_2)
            for elem in self.roi_rect:
                painter.drawPoint(elem)
            # for elem in self.img_rect:
            # painter.drawPoint(elem)
            if self.default_rect:
                self.update()
示例#10
0
    def draw_polygons(self, event):
        if self.polygons:
            painter = QPainter(self)

            # painter.drawEllipse(0, 0, self.width()/2, self.width()/2)
            for (pa, pb, pc), color in self.polygons:
                a = QPoint(pa.x, pa.y)
                b = QPoint(pb.x, pb.y)
                c = QPoint(pc.x, pc.y)

                pen = QPen()

                if color:
                    pen.setColor(color)
                else:
                    pen.setColor(QColor(0, 0, 0))

                painter.setPen(pen)

                polygon = QPolygonF([a, b, c])

                painter.drawPolygon(polygon)

                if color:
                    path = QPainterPath()
                    path.addPolygon(polygon)

                    # painter.setBrush(QBrush(color))
                    painter.fillPath(path, QBrush(color))
示例#11
0
    def shape(self):
        #path = super().shape()
        path = QPainterPath()
        #path.addRect(self.calcRect())
        path.addPolygon(self.arrowHead)

        return path
示例#12
0
文件: Blob.py 项目: ldelprete/TagLab
    def setupForDrawing(self):
        """
        Create the QPolygon and the QPainterPath according to the blob's contours.
        """

        # QPolygon to draw the blob
        #working with mask the center of the pixels is in 0, 0
        #if drawing the center of the pixel is 0.5, 0.5
        qpolygon = QPolygonF()
        for i in range(self.contour.shape[0]):
            qpolygon << QPointF(self.contour[i, 0] + 0.5,
                                self.contour[i, 1] + 0.5)

        self.qpath = QPainterPath()
        self.qpath.addPolygon(qpolygon)

        for inner_contour in self.inner_contours:
            qpoly_inner = QPolygonF()
            for i in range(inner_contour.shape[0]):
                qpoly_inner << QPointF(inner_contour[i, 0], inner_contour[i,
                                                                          1])

            path_inner = QPainterPath()
            path_inner.addPolygon(qpoly_inner)
            self.qpath = self.qpath.subtracted(path_inner)
示例#13
0
    def FOV(self, Robo):

        view = QPainterPath()

        xPos = math.cos(math.radians(Robo.alpha +
                                     (Robo.FOV / 2))) * Robo.radius
        yPos = math.sin(math.radians(Robo.alpha +
                                     (Robo.FOV / 2))) * Robo.radius

        xPos2 = math.cos(math.radians(Robo.alpha -
                                      (Robo.FOV / 2))) * Robo.radius
        yPos2 = math.sin(math.radians(Robo.alpha -
                                      (Robo.FOV / 2))) * Robo.radius

        x1 = QPoint(
            int(round(Robo.position.x())) + Robo.radius,
            int(round(Robo.position.y())) + Robo.radius)
        x2 = x1 + QPoint(
            (int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos,
            (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos)
        x3 = x1 + QPoint(
            (int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos2,
            (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos2)

        view.addPolygon(QPolygonF([x1, x2, x3]))
        view.closeSubpath()

        return view
示例#14
0
 def painterPath(self):
     """
     Returns the current shape as QPainterPath (used for collision detection).
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     return path
示例#15
0
 def shape(self):
     """
     Returns the shape of this item as a QPainterPath in local coordinates.
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     return path
示例#16
0
 def shape(self):
     """
     Returns the shape of this item as a QPainterPath in local coordinates.
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     return path
示例#17
0
 def painterPath(self):
     """
     Returns the current shape as QPainterPath (used for collision detection).
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     return path
示例#18
0
class Segment(QGraphicsItem):
    def __init__(self, color, offset, parent):
        super(Segment, self).__init__(parent)
        self.color = color
        # 每节的身体段
        self.rect = QRectF(offset, -20, 30, 40)
        self.path = QPainterPath()
        self.path.addEllipse(self.rect)

        # 每节的左腿
        x = offset + 15
        y = -20
        self.path.addPolygon(
            QPolygonF(
                [QPointF(x, y),
                 QPointF(x - 5, y - 18),
                 QPointF(x - 5, y)]))
        self.path.closeSubpath()
        # 每节的右腿
        y = 20
        self.path.addPolygon(
            QPolygonF(
                [QPointF(x, y),
                 QPointF(x - 5, y + 18),
                 QPointF(x - 5, y)]))
        self.path.closeSubpath()
        self.change = 1
        self.angle = 0

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

    def shape(self):
        return self.path

    def paint(self, painter, option, widget=None):
        painter.setPen(Qt.NoPen)
        painter.setBrush(QBrush(self.color))
        if option.levelOfDetailFromTransform(self.transform()) < 0.9:
            painter.drawEllipse(self.rect)
        else:
            painter.drawPath(self.path)

    def advance(self, phase):
        if phase == 0:
            matrix = self.transform()
            matrix.reset()
            self.setTransform(matrix)
            self.angle += self.change * random.random()
            if self.angle > 6:
                self.change = -1
                # self.angle -= 0.00001
            elif self.angle < -6:
                self.change = 1
                # self.angle += 0.00001
        elif phase == 1:
            self.setRotation(self.angle)
示例#19
0
 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)
示例#20
0
 def getPath(self) -> QPainterPath:
     pol = QPolygonF()
     pol.append(self._firstPoint)
     for p in self._midPoints:
         pol.append(p)
     pol.append(self._lastPoint)
     ans = QPainterPath()
     ans.addPolygon(pol)
     return ans
示例#21
0
class Segment(QGraphicsItem):
    def __init__(self, color, offset, parent):
        super(Segment, self).__init__(parent)
        self.color = color
        self.rect = QRectF(offset, -20, 30, 40)
        self.path = QPainterPath()
        self.path.addEllipse(self.rect)
        x = offset + 15
        y = -20
        self.path.addPolygon(
            QPolygonF(
                [QPointF(x, y),
                 QPointF(x - 5, y - 12),
                 QPointF(x - 5, y)]))
        self.path.closeSubpath()
        y = 20
        self.path.addPolygon(
            QPolygonF(
                [QPointF(x, y),
                 QPointF(x - 5, y + 12),
                 QPointF(x - 5, y)]))
        self.path.closeSubpath()
        self.change = 1
        self.angle = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.timeout)
        self.timer.start(INTERVAL)

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

    def shape(self):
        return self.path

    def paint(self, painter, option, widget=None):
        painter.setPen(Qt.NoPen)
        painter.setBrush(QBrush(self.color))
        if option.levelOfDetailFromTransform(self.transform()) < 0.9:
            painter.drawEllipse(self.rect)
        else:
            painter.drawPath(self.path)

    def timeout(self):
        if not Running:
            return
        matrix = self.transform()
        matrix.reset()
        self.setTransform(matrix)
        self.angle += self.change * random.random()
        if self.angle > 4.5:
            self.change = -1
            self.angle -= 0.00001
        elif self.angle < -4.5:
            self.change = 1
            self.angle += 0.00001
        self.setRotation(self.angle)
示例#22
0
 def view_cone(self):
     path = QPainterPath()
     a = self.pos.toPointF()
     b = a + QPointF(5000 * math.cos(math.radians(self.alpha + self.aov)),
                     5000 * math.sin(math.radians(self.alpha + self.aov)))
     c = a + QPointF(5000 * math.cos(math.radians(self.alpha - self.aov)),
                     5000 * math.sin(math.radians(self.alpha - self.aov)))
     path.addPolygon(QPolygonF([a, b, c]))
     path.closeSubpath()
     return path
示例#23
0
    def shape(self):
        if self._stock_polygon == NodePolygon.Circle:
            path = super().shape()
        else:
            path = QPainterPath()
            path.addPolygon(self._node_polygon)

        label_path = QPainterPath()
        label_path.addRect(self._label_rect)
        return path.united(label_path)
示例#24
0
 def shape(self):
     """
     Returns the shape of this item as a QPainterPath in local coordinates.
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     for shape in self.handleBound:
         path.addEllipse(shape)
     return path
示例#25
0
 def pathForPointV1(self, point, scene, rsize=3):
     view = scene.views()[0]
     pc = view.mapFromScene(point)
     dp = QPoint(rsize, rsize)
     recv = QRect(pc - dp, pc + dp)
     poly = view.mapToScene(recv)
     path = QPainterPath()
     path.addPolygon(poly)
     path.closeSubpath()
     return path
示例#26
0
 def shape(self):
     """
     Returns the shape of this item as a QPainterPath in local coordinates.
     :rtype: QPainterPath
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     for shape in self.handleBound:
         path.addEllipse(shape)
     return path
示例#27
0
 def shape(self):
     """
     Returns the shape of this item as a QPainterPath in local coordinates.
     """
     path = QPainterPath()
     path.addPolygon(self.polygon)
     if self.isSelected():
         for shape in self.handles.values():
             path.addEllipse(shape)
     return path
示例#28
0
 def shape(self):
     #TODO: add proper path corresponding to bounding rect
     #has to be implemented, otherwise bounding rect is the assumed shape
     path = QPainterPath()
     polygon = QPolygonF()
     polygon.append(QPointF(Triangle.a/2, 0))
     polygon.append(QPointF(0, Triangle.h))
     polygon.append(QPointF(Triangle.a, Triangle.h))
     polygon.append(QPointF(Triangle.a+Triangle.a/2, 0))
     path.addPolygon(polygon)
     return path
示例#29
0
    def drawBody(self, qp):
        #画身体
        path4 = QPainterPath()
        body_polygon = QPolygonF()
        body_polygon << QPointF(316.0, 349.0) << QPointF(
            580.0, 349.0) << QPointF(577.0, 496.0) << QPointF(319.0, 496.0)
        # 绘制一个多边形
        path4.addPolygon(body_polygon)
        path4.closeSubpath()
        qp.setBrush(QColor(156, 214, 239))
        qp.drawPath(path4)

        #画肚子
        path5 = QPainterPath()
        belly_width = 180.0
        belly_length = 235.0
        bellyre = QRectF(365.0, 240.0, belly_width, belly_length)
        belly_center_x = 365.0 + belly_width / 2
        belly_center_y = 240.0 + belly_length / 2
        path5.moveTo(belly_center_x, belly_center_y)
        path5.arcTo(bellyre, 180, 180)
        path5.closeSubpath()
        qp.setBrush(Qt.white)
        qp.drawPath(path5)

        #画围兜
        path6 = QPainterPath()
        scarf_polygon = QPolygonF()
        scarf_polygon << QPointF(316.0, 349.0) << QPointF(
            580.0, 349.0) << QPointF(450.0, 379.0) << QPointF(319.0, 349.0)
        path6.addPolygon(scarf_polygon)
        path6.closeSubpath()
        qp.setBrush(Qt.red)
        qp.drawPath(path6)

        #画铃铛
        bell_re = QRectF(442.0, 364.0, 30, 30)
        qp.setBrush(QColor(250, 221, 81))
        qp.drawEllipse(bell_re)
        qp.drawLine(455, 370, 465, 380)
        qp.drawLine(465, 380, 455, 385)

        #画口袋
        path7 = QPainterPath()
        pocket_width = 112.0
        pocket_length = 104.0
        pocketre = QRectF(400.0, 352.0, pocket_width, pocket_length)
        pocket_center_x = 412.0 + pocket_width / 2
        pocket_center_y = 352.0 + pocket_length / 2
        path7.moveTo(pocket_center_x, pocket_center_y)
        path7.arcTo(pocketre, 180, 180)
        path7.closeSubpath()
        qp.setBrush(Qt.white)
        qp.drawPath(path7)
示例#30
0
    def updatePath(self):
        try:
            attrs = self.stackedWidget.currentWidget().get_attributes()
            attrs.keys()
        except Exception as e:
            msg = 'Tracking Lib. Attributes Error:\n{}'.format(e)
            self.generateCriticalMessage(msg)
            return

        if 'position' in attrs:
            self.trackingPathGroup.setPoints(self.currentFrameNo)

        if 'arrow' in attrs:
            for i, arrow_item in enumerate(self.item_dict['arrow']):
                begin = self.df['position'].loc[self.currentFrameNo, i].as_matrix()
                end = self.df['arrow'].loc[self.currentFrameNo, i].as_matrix()
                arrow_item.setPosition(begin, end)

        if 'path' in attrs:
            for path_item, path_data in zip(self.item_dict['path'], self.data_dict['path'][self.currentFrameNo]):
                poly = QPolygonF()
                for p in path_data:
                    poly.append(QPointF(*p))

                painter_path = QPainterPath()
                painter_path.addPolygon(poly)
                path_item.setPath(painter_path)

                pen = QPen(Qt.blue)
                pen.setWidth(2)
                path_item.setPen(pen)

        if 'polygon' in attrs:
            for path_item, path_data in zip(self.item_dict['polygon'], self.data_dict['polygon'][self.currentFrameNo]):
                poly = QPolygonF()
                for p in path_data:
                    poly.append(QPointF(*p))

                painter_path = QPainterPath()
                painter_path.addPolygon(poly)
                path_item.setPath(painter_path)

                pen = QPen(Qt.black)
                pen.setWidth(1)
                path_item.setPen(pen)

        if 'rect' in attrs:
            for rect_item, rect in zip(self.item_dict['rect'], self.data_dict['rect'][self.currentFrameNo]):
                rect_item.setRect(QRectF(QPointF(*rect[0]), QPointF(*rect[1])))
示例#31
0
    def updatePath(self):
        try:
            attrs = self.stackedWidget.currentWidget().get_attributes()
            attrs.keys()
        except Exception as e:
            msg = 'Tracking Lib. Attributes Error:\n{}'.format(e)
            self.generateCriticalMessage(msg)
            return

        if 'position' in attrs:
            self.trackingPathGroup.setPoints(self.currentFrameNo)

        if 'arrow' in attrs:
            for i, arrow_item in enumerate(self.item_dict['arrow']):
                begin = self.df['position'].loc[self.currentFrameNo, i].values
                end = self.df['arrow'].loc[self.currentFrameNo, i].values
                arrow_item.setPosition(begin, end)

        if 'path' in attrs:
            for path_item, path_data in zip(self.item_dict['path'], self.data_dict['path'][self.currentFrameNo]):
                poly = QPolygonF()
                for p in path_data:
                    poly.append(QPointF(*p))

                painter_path = QPainterPath()
                painter_path.addPolygon(poly)
                path_item.setPath(painter_path)

                pen = QPen(Qt.blue)
                pen.setWidth(2)
                path_item.setPen(pen)

        if 'polygon' in attrs:
            for path_item, path_data in zip(self.item_dict['polygon'], self.data_dict['polygon'][self.currentFrameNo]):
                poly = QPolygonF()
                for p in path_data:
                    poly.append(QPointF(*p))

                painter_path = QPainterPath()
                painter_path.addPolygon(poly)
                path_item.setPath(painter_path)

                pen = QPen(Qt.black)
                pen.setWidth(1)
                path_item.setPen(pen)

        if 'rect' in attrs:
            for rect_item, rect in zip(self.item_dict['rect'], self.data_dict['rect'][self.currentFrameNo]):
                rect_item.setRect(QRectF(QPointF(*rect[0]), QPointF(*rect[1])))
示例#32
0
    def boundingRect(self):
        """
        Returns the shape bounding rect.
        :rtype: QRectF
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        for shape in self.handles:
            path.addEllipse(shape)
        for shape in self.anchors.values():
            path.addEllipse(shape)

        return path.controlPointRect()
示例#33
0
    def boundingRect(self):
        """
        Returns the shape bounding rect.
        :rtype: QRectF
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        for shape in self.handles:
            path.addEllipse(shape)
        for shape in self.anchors.values():
            path.addEllipse(shape)

        return path.controlPointRect()
示例#34
0
 def renderImage(self, remove_useless_background=False):
     if not self.Image:
         return
     paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32)
     paintedImage.fill(Qt.transparent)
     painter = QPainter(paintedImage)
     if self.cropPolygon:
         painterPath = QPainterPath()
         painterPath.addPolygon(self.cropPolygon)
         painter.setClipPath(painterPath)
     painter.drawImage(QPoint(), self.Image)
     painter.end()
     if remove_useless_background:
         return paintedImage.copy(painterPath.boundingRect().toRect())
     else:
         return paintedImage
示例#35
0
    def shape(self):
        """
        Returns the shape of this item as a QPainterPath in local coordinates.
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        if self.isSelected():
            for shape in self.handles:
                path.addEllipse(shape)
            for shape in self.anchors.values():
                path.addEllipse(shape)

        return path
示例#36
0
    def shape(self):
        """
        Returns the shape of this item as a QPainterPath in local coordinates.
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        if self.isSelected():
            for shape in self.handles:
                path.addEllipse(shape)
            for shape in self.anchors.values():
                path.addEllipse(shape)

        return path
示例#37
0
		def uiBatteryIconPaintEvent(evt, rectSize=24):
			"""Draw the little coloured square on the focus peaking button."""
			if self._batteryPresent and (self._batteryCharging or not self._batteryBlink):
				powerDownLevel = api.apiValues.get('powerOffWhenMainsLost') * self.uiPowerDownThreshold
				warningLevel = powerDownLevel + 0.15
				
				x,y,w,h = (
					1,
					1,
					self.uiBatteryIcon.width() - 2,
					self.uiBatteryIcon.height() - 1,
				)
				
				p = QPainter(self.uiBatteryIcon)
				
				#Cut out the battery outline, so the battery fill level doesn't show by
				#outside the "nub". Nextly, this was taken care of by an opaque box
				#outside the battery nub in the SVG image, but this didn't work so well
				#when the button was pressed or when themes were changed. We can't fill
				#a polygon a percentage of the way very easily, and we can't just go in
				#and muck with the SVG to achieve this either like we would in browser.
				batteryOutline = QPainterPath()
				batteryOutline.addPolygon(QPolygonF([
					QPoint(x+3,y),
					QPoint(x+3,y+2), #Left battery nub chunk.
					QPoint(x,y+2),
					QPoint(x,y+h), #Bottom
					QPoint(x+w,y+h),
					QPoint(x+w,y+2),
					QPoint(x+w-3,y+2), #Right battery nub chunk.
					QPoint(x+w-3,y),
				]))
				batteryOutline.closeSubpath() #Top of battery nub.
				p.setClipPath(batteryOutline, Qt.IntersectClip)
				
				p.setPen(QPen(QColor('transparent')))
				
				if self._batteryCharge > warningLevel or self._batteryCharging:
					p.setBrush(QBrush(QColor('#00b800')))
				else:
					p.setBrush(QBrush(QColor('#f20000')))
				p.drawRect(
					x, y + h * (1-self._batteryCharge),
					w, h * self._batteryCharge )
			type(self.uiBatteryIcon).paintEvent(self.uiBatteryIcon, evt) #Invoke the superclass to paint the battery overlay image on our new rect.
示例#38
0
def arrow(x0, x1, arrow_size=0.3, arrow_angle=pi/5):
    dx, dy = x1 - x0
    if dy**2 + dx**2 < arrow_size**2:
        return None
    path = QPainterPath()
    path.moveTo(*x0)
    path.lineTo(*x1)
    angle = atan2(dy, dx)
    p1 = x1 + [cos(angle + pi + arrow_angle) * arrow_size,
               sin(angle + pi + arrow_angle) * arrow_size]
    p2 = x1 + [cos(angle + pi - arrow_angle) * arrow_size,
               sin(angle + pi - arrow_angle) * arrow_size]
    path.addPolygon(QPolygonF([
        QPointF(*x1),
        QPointF(*p1),
        QPointF(*p2),
        QPointF(*x1),
    ]))
    return path
示例#39
0
def _createPreXoverPainterPath( elements: List[List[QPointF]],
                                end_poly: QPolygonF = None,
                                is_fwd: bool = True) -> QPainterPath:
    path = QPainterPath()

    next_pt = None
    for element in elements:
        start_pt = element[0]
        path.moveTo(start_pt)
        for next_pt in element[1:]:
            path.lineTo(next_pt)

    if end_poly is not None:
        h = end_poly.boundingRect().height()/2
        xoffset = -h if is_fwd else h
        w = end_poly.boundingRect().width()
        yoffset = w if is_fwd else -w
        angle = -90 if is_fwd else 90
        T = QTransform()
        T.translate(next_pt.x()+xoffset, next_pt.y()+yoffset)
        T.rotate(angle)
        path.addPolygon(T.map(end_poly))
    return path
示例#40
0
    def shape(self):
        """
        Return real shape of the item to detect collision or hover accurately

        :return: QPainterPath
        """
        # detection mouse hover on arc path
        path = QPainterPath()
        path.addPolygon(QPolygonF([self.line().p1(), self.line().p2()]))
        #  add handles at the start and end of arc
        path.addRect(QRectF(
            self.line().p1().x() - 5,
            self.line().p1().y() - 5,
            self.line().p1().x() + 5,
            self.line().p1().y() + 5
        ))
        path.addRect(QRectF(
            self.line().p2().x() - 5,
            self.line().p2().y() - 5,
            self.line().p2().x() + 5,
            self.line().p2().y() + 5
        ))
        return path
    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()
示例#42
0
"""
from PyQt5.QtCore import QRectF, QPointF
from PyQt5.QtGui import QPainterPath, QPolygonF
from cadnano.gui.views.pathview import pathstyles as styles
from cadnano.gui.palette import getPenObj
from .abstractpathtool import AbstractPathTool

_BW = styles.PATH_BASE_WIDTH
_PEN = getPenObj(styles.RED_STROKE, 1)
_RECT = QRectF(0, 0, _BW, _BW)
_PATH_ARROW_LEFT = QPainterPath()
_L3_POLY = QPolygonF()
_L3_POLY.append(QPointF(_BW, 0))
_L3_POLY.append(QPointF(0.25 * _BW, 0.5 * _BW))
_L3_POLY.append(QPointF(_BW, _BW))
_PATH_ARROW_LEFT.addPolygon(_L3_POLY)
_PATH_ARROW_RIGHT = QPainterPath()
_R3_POLY = QPolygonF()  # right-hand 3' arr
_R3_POLY.append(QPointF(0, 0))
_R3_POLY.append(QPointF(0.75 * _BW, 0.5 * _BW))
_R3_POLY.append(QPointF(0, _BW))
_PATH_ARROW_RIGHT.addPolygon(_R3_POLY)


class BreakTool(AbstractPathTool):
    """
    docstring for BreakTool
    """
    def __init__(self, manager):
        """Summary
示例#43
0
class InclusionEdge(AbstractEdge):
    """
    This class implements the Inclusion edge.
    """
    item = Item.InclusionEdge

    def __init__(self, complete=False, **kwargs):
        """
        Initialize the edge.
        :type complete: bool
        """
        super().__init__(**kwargs)
        self.complete = complete
        self.tail = QPolygonF()

    ####################################################################################################################
    #                                                                                                                  #
    #   INTERFACE                                                                                                      #
    #                                                                                                                  #
    ####################################################################################################################

    def copy(self, scene):
        """
        Create a copy of the current edge.
        :type scene: DiagramScene
        """
        kwargs = {
            'id': self.id,
            'source': self.source,
            'target': self.target,
            'breakpoints': self.breakpoints[:],
            'complete': self.complete,
        }
        return scene.factory.create(item=self.item, scene=scene, **kwargs)

    @staticmethod
    def createHead(pos1, angle, size):
        """
        Create the head polygon.
        :type pos1: QPointF
        :type angle: float
        :type size: int
        :rtype: QPolygonF
        """
        rad = radians(angle)
        pos2 = pos1 - QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size)
        pos3 = pos1 - QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size)
        return QPolygonF([pos1, pos2, pos3])

    @staticmethod
    def createTail(pos1, angle, size):
        """
        Create the tail polygon.
        :type pos1: QPointF
        :type angle: float
        :type size: int
        :rtype: QPolygonF
        """
        rad = radians(angle)
        pos2 = pos1 + QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size)
        pos3 = pos1 + QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size)
        return QPolygonF([pos1, pos2, pos3])

    ####################################################################################################################
    #                                                                                                                  #
    #   GEOMETRY                                                                                                       #
    #                                                                                                                  #
    ####################################################################################################################

    def boundingRect(self):
        """
        Returns the shape bounding rect.
        :rtype: QRectF
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)
        path.addPolygon(self.tail)

        for shape in self.handles:
            path.addEllipse(shape)
        for shape in self.anchors.values():
            path.addEllipse(shape)

        return path.controlPointRect()

    def painterPath(self):
        """
        Returns the current shape as QPainterPath (used for collision detection).
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.path)
        path.addPolygon(self.head)
        path.addPolygon(self.tail)
        return path

    def shape(self):
        """
        Returns the shape of this item as a QPainterPath in local coordinates.
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)
        path.addPolygon(self.tail)

        if self.isSelected():
            for shape in self.handles:
                path.addEllipse(shape)
            for shape in self.anchors.values():
                path.addEllipse(shape)

        return path

    ####################################################################################################################
    #                                                                                                                  #
    #   GEOMETRY UPDATE                                                                                                #
    #                                                                                                                  #
    ####################################################################################################################

    def updateEdge(self, target=None):
        """
        Update the edge painter path and the selection polygon.
        :type target: QPointF
        """
        boxSize = self.selectionSize
        headSize = self.headSize
        sourceNode = self.source
        targetNode = self.target
        sourcePos = sourceNode.anchor(self)
        targetPos = target or targetNode.anchor(self)

        self.prepareGeometryChange()

        self.updateAnchors()
        self.updateBreakPoints()
        self.updateZValue()

        createSelectionArea = self.createSelectionArea
        createHead = self.createHead
        createTail = self.createTail

        ################################################################################################################
        #                                                                                                              #
        #   UPDATE EDGE PATH, SELECTION BOX, HEAD AND TAIL                                                             #
        #                                                                                                              #
        ################################################################################################################

        collection = self.computePath(sourceNode, targetNode, [sourcePos] + self.breakpoints + [targetPos])

        self.path = QPainterPath()
        self.selection = QPainterPath()
        self.head = QPolygonF()
        self.tail = QPolygonF()

        if len(collection) == 1:

            subpath = collection[0]
            p1 = sourceNode.intersection(subpath)
            p2 = targetNode.intersection(subpath) if targetNode else subpath.p2()
            if p1 is not None and p2 is not None:
                self.path.moveTo(p1)
                self.path.lineTo(p2)
                self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize))
                self.head = createHead(p2, subpath.angle(), headSize)
                if self.complete:
                    self.tail = createTail(p1, subpath.angle(), headSize)

        elif len(collection) > 1:

            subpath1 = collection[0]
            subpathN = collection[-1]
            p11 = sourceNode.intersection(subpath1)
            p22 = targetNode.intersection(subpathN)

            if p11 and p22:

                p12 = subpath1.p2()
                p21 = subpathN.p1()

                self.path.moveTo(p11)
                self.path.lineTo(p12)
                self.selection.addPolygon(createSelectionArea(p11, p12, subpath1.angle(), boxSize))

                for subpath in collection[1:-1]:
                    p1 = subpath.p1()
                    p2 = subpath.p2()
                    self.path.moveTo(p1)
                    self.path.lineTo(p2)
                    self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize))

                self.path.moveTo(p21)
                self.path.lineTo(p22)
                self.selection.addPolygon(createSelectionArea(p21, p22, subpathN.angle(), boxSize))

                self.head = createHead(p22, subpathN.angle(), headSize)
                if self.complete:
                    self.tail = createTail(p11, subpath1.angle(), headSize)

        self.updateBrush(selected=self.isSelected(), visible=self.canDraw())

    ####################################################################################################################
    #                                                                                                                  #
    #   DRAWING                                                                                                        #
    #                                                                                                                  #
    ####################################################################################################################

    @classmethod
    def image(cls, **kwargs):
        """
        Returns an image suitable for the palette.
        :rtype: QPixmap
        """
        # INITIALIZATION
        pixmap = QPixmap(kwargs['w'], kwargs['h'])
        pixmap.fill(Qt.transparent)
        painter = QPainter(pixmap)
        # INIT THE LINE
        p1 = QPointF(((kwargs['w'] - 54) / 2), kwargs['h'] / 2)
        p2 = QPointF(((kwargs['w'] - 54) / 2) + 54 - 2, kwargs['h'] / 2)
        line = QLineF(p1, p2)
        # CLACULATE HEAD COORDS
        angle = line.angle()
        p1 = QPointF(line.p2().x() + 2, line.p2().y())
        p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8)
        p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8)
        # INITIALIZE HEAD
        head = QPolygonF([p1, p2, p3])
        # DRAW EDGE LINE
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        # DRAW EDGE HEAD
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.setBrush(QColor(0, 0, 0))
        painter.drawPolygon(head)
        return pixmap

    def paint(self, painter, option, widget=None):
        """
        Paint the edge in the diagram scene.
        :type painter: QPainter
        :type option: QStyleOptionGraphicsItem
        :type widget: QWidget
        """
        # SET THE RECT THAT NEEDS TO BE REPAINTED
        painter.setClipRect(option.exposedRect)
        # SELECTION AREA
        painter.setRenderHint(QPainter.Antialiasing)
        painter.fillPath(self.selection, self.selectionBrush)
        # EDGE LINE
        painter.setPen(self.pen)
        painter.drawPath(self.path)
        # HEAD/TAIL POLYGON
        painter.setPen(self.headPen)
        painter.setBrush(self.headBrush)
        painter.drawPolygon(self.head)
        painter.drawPolygon(self.tail)
        # BREAKPOINTS AND ANCHOR POINTS
        painter.setPen(self.handlePen)
        painter.setBrush(self.handleBrush)
        for shape in self.handles:
            painter.drawEllipse(shape)
        for shape in self.anchors.values():
            painter.drawEllipse(shape)
示例#44
0
BASE_WIDTH = styles.PATH_BASE_WIDTH
BASE_RECT = QRectF(0, 0, BASE_WIDTH, BASE_WIDTH)


PHOS_ITEM_WIDTH = 0.25*BASE_WIDTH
TRIANGLE = QPolygonF()
TRIANGLE.append(QPointF(0, 0))
TRIANGLE.append(QPointF(0.75 * PHOS_ITEM_WIDTH, 0.5 * PHOS_ITEM_WIDTH))
TRIANGLE.append(QPointF(0, PHOS_ITEM_WIDTH))
TRIANGLE.append(QPointF(0, 0))
TRIANGLE.translate(0, -0.5*PHOS_ITEM_WIDTH)
T180 = QTransform()
T180.rotate(-180)
FWDPHOS_PP, REVPHOS_PP = QPainterPath(), QPainterPath()
FWDPHOS_PP.addPolygon(TRIANGLE)
REVPHOS_PP.addPolygon(T180.map(TRIANGLE))

KEYINPUT_ACTIVE_FLAG = QGraphicsItem.ItemIsFocusable

PROX_ALPHA = 64

class PropertyWrapperObject(QObject):
    """
    Attributes:
        animations (dict): Description
        brush_alpha (TYPE): Description
        item (TYPE): Description
        rotation (TYPE): Description
    """
示例#45
0
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)

        contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect()  # the SE_FrameContents rect is Null unless the stylesheet defines decorations

        if self.graphStyle == self.BarStyle:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit))
        else:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1)

        max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled)))

        if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0:
            graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight)
        else:
            graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight)

        if self.graphStyle == self.BarStyle:
            height_scaling = float(contents_rect.height()) / graph_height
        else:
            height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height

        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

        painter.setClipRect(contents_rect)

        painter.save()
        painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1)
        painter.scale(-1, -1)

        painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle)

        for graph in (graph for graph in self.graphs if graph.enabled and graph.data):
            if self.boundary is not None and 0 < self.boundary < graph_height:
                boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary)
                pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                pen_color.setColorAt(0, graph.color)
                pen_color.setColorAt(1, graph.over_boundary_color)
                brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency))
                brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency))
            else:
                pen_color = graph.color
                brush_color = self.color_with_alpha(graph.color, self.fillTransparency)
            dataset = islice(reversed(graph.data), graph_width)
            if self.graphStyle == self.BarStyle:
                lines = [QLineF(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]
                painter.setPen(QPen(pen_color, self.lineThickness))
                painter.drawLines(lines)
            else:
                painter.translate(0, +self.lineThickness/2 - 1)

                if self.smoothEnvelope and self.smoothFactor > 0:
                    min_value = 0
                    max_value = graph_height * height_scaling
                    cx_offset = self.horizontalPixelsPerUnit / 3.0
                    smoothness = self.smoothFactor

                    last_values = deque(3*[next(dataset) * height_scaling], maxlen=3)  # last 3 values: 0 last, 1 previous, 2 previous previous

                    envelope = QPainterPath()
                    envelope.moveTo(0, last_values[0])
                    for x, y in enumerate(dataset, 1):
                        x = x * self.horizontalPixelsPerUnit
                        y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness
                        last_values.appendleft(y)
                        c1x = x - cx_offset * 2
                        c2x = x - cx_offset
                        c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value)  # same gradient as previous previous value to previous value
                        c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value)  # same gradient as previous value to last value
                        envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
                else:
                    envelope = QPainterPath()
                    envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]))

                if self.fillEnvelope or graph.fill_envelope:
                    first_element = envelope.elementAt(0)
                    last_element = envelope.elementAt(envelope.elementCount() - 1)
                    fill_path = QPainterPath()
                    fill_path.moveTo(last_element.x, last_element.y)
                    fill_path.lineTo(last_element.x + 1, last_element.y)
                    fill_path.lineTo(last_element.x + 1, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, first_element.y)
                    fill_path.connectPath(envelope)
                    painter.fillPath(fill_path, brush_color)

                painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin))

                painter.translate(0, -self.lineThickness/2 + 1)

        if self.boundary is not None and self.boundaryColor:
            painter.setRenderHint(QStylePainter.Antialiasing, False)
            painter.setPen(QPen(self.boundaryColor, 1.0))
            painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling)

        painter.restore()

        # queue the 'updated' signal to be emitted after returning to the main loop
        QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
示例#46
0
PP_53 = QPainterPath()  # Left 5', Right 3' PainterPath
PP_35 = QPainterPath()  # Left 5', Right 3' PainterPath
# set up PP_L5 (left 5' blue square)
PP_L5.addRect(0.25 * _BASE_WIDTH,
            0.125 * _BASE_WIDTH,
            0.75 * _BASE_WIDTH,
            0.75 * _BASE_WIDTH)
# set up PP_R5 (right 5' blue square)
PP_R5.addRect(0, 0.125 * _BASE_WIDTH, 0.75 * _BASE_WIDTH, 0.75 * _BASE_WIDTH)
# set up PP_L3 (left 3' blue triangle)
L3_POLY = QPolygonF()
L3_POLY.append(QPointF(_BASE_WIDTH, 0))
L3_POLY.append(QPointF(0.25 * _BASE_WIDTH, 0.5 * _BASE_WIDTH))
L3_POLY.append(QPointF(_BASE_WIDTH, _BASE_WIDTH))
L3_POLY.append(QPointF(_BASE_WIDTH, 0))
PP_L3.addPolygon(L3_POLY)
# set up PP_R3 (right 3' blue triangle)
R3_POLY = QPolygonF()
R3_POLY.append(QPointF(0, 0))
R3_POLY.append(QPointF(0.75 * _BASE_WIDTH, 0.5 * _BASE_WIDTH))
R3_POLY.append(QPointF(0, _BASE_WIDTH))
R3_POLY.append(QPointF(0, 0))
PP_R3.addPolygon(R3_POLY)

# single base left 5'->3'
PP_53.addRect(0, 0.125 * _BASE_WIDTH, 0.5 * _BASE_WIDTH, 0.75 * _BASE_WIDTH)
POLY_53 = QPolygonF()
POLY_53.append(QPointF(0.5 * _BASE_WIDTH, 0))
POLY_53.append(QPointF(_BASE_WIDTH, 0.5 * _BASE_WIDTH))
POLY_53.append(QPointF(0.5 * _BASE_WIDTH, _BASE_WIDTH))
PP_53.addPolygon(POLY_53)
示例#47
0
PPL5 = QPainterPath()  # Left 5' PainterPath
PPR5 = QPainterPath()  # Right 5' PainterPath
PPL3 = QPainterPath()  # Left 3' PainterPath
PPR3 = QPainterPath()  # Right 3' PainterPath

# set up PPL5 (left 5' blue square)
PPL5.addRect(0.25*_BASE_WIDTH, 0.125*_BASE_WIDTH, 0.75*_BASE_WIDTH, 0.75*_BASE_WIDTH)
# set up PPR5 (right 5' blue square)
PPR5.addRect(0, 0.125*_BASE_WIDTH, 0.75*_BASE_WIDTH, 0.75*_BASE_WIDTH)
# set up PPL3 (left 3' blue triangle)
L3_POLY = QPolygonF()
L3_POLY.append(QPointF(_BASE_WIDTH, 0))
L3_POLY.append(QPointF(0.25*_BASE_WIDTH, 0.5*_BASE_WIDTH))
L3_POLY.append(QPointF(_BASE_WIDTH, _BASE_WIDTH))
PPL3.addPolygon(L3_POLY)
# set up PPR3 (right 3' blue triangle)
R3_POLY = QPolygonF()
R3_POLY.append(QPointF(0, 0))
R3_POLY.append(QPointF(0.75*_BASE_WIDTH, 0.5*_BASE_WIDTH))
R3_POLY.append(QPointF(0, _BASE_WIDTH))
PPR3.addPolygon(R3_POLY)


class ForcedXoverNode3(QGraphicsRectItem):
    """
    This is a QGraphicsRectItem to allow actions and also a
    QGraphicsSimpleTextItem to allow a label to be drawn

    Attributes:
        is_forward (TYPE): Description
示例#48
0
PXI_PP_ITEM_WIDTH = IW = 2.0  # 1.5
TRIANGLE = QPolygonF()
TRIANGLE.append(QPointF(0, 0))
TRIANGLE.append(QPointF(0.75*IW, 0.5*IW))
TRIANGLE.append(QPointF(0, IW))
TRIANGLE.append(QPointF(0, 0))
# TRIANGLE.translate(-0.75*IW, -0.5*IW)
TRIANGLE.translate(-0.25*IW, -0.5*IW)

PXI_RECT = QRectF(0, 0, IW, IW)
T90, T270 = QTransform(), QTransform()
T90.rotate(90)
T270.rotate(270)
FWDPXI_PP, REVPXI_PP = QPainterPath(), QPainterPath()
FWDPXI_PP.addPolygon(T90.map(TRIANGLE))
REVPXI_PP.addPolygon(T270.map(TRIANGLE))

# FWDPXI_PP.moveTo(-0.5*IW, 0.7*IW)
# FWDPXI_PP.lineTo(0., -0.2*IW)
# FWDPXI_PP.lineTo(0.5*IW, 0.7*IW)
# extra1 = QPainterPath()
# extra1.addEllipse(-0.5*IW, 0.5*IW, IW, 0.4*IW)
# extra2 = QPainterPath()
# extra2.addEllipse(-0.35*IW, 0.5*IW, 0.7*IW, 0.3*IW)
# FWDPXI_PP += extra1
# FWDPXI_PP -= extra2

# REVPXI_PP.moveTo(-0.5*IW, -0.7*IW)
# REVPXI_PP.lineTo(0., 0.2*IW)
# REVPXI_PP.lineTo(0.5*IW, -0.7*IW)
示例#49
0
	def paint(self, painter, option, index):
		assert isinstance(painter, QPainter)
		if index.data(Qt.UserRole+1):
			if app_constants.HIGH_QUALITY_THUMBS:
				painter.setRenderHint(QPainter.SmoothPixmapTransform)
			painter.setRenderHint(QPainter.Antialiasing)
			gallery = index.data(Qt.UserRole+1)
			title = gallery.title
			artist = gallery.artist
			title_color = app_constants.GRID_VIEW_TITLE_COLOR
			artist_color = app_constants.GRID_VIEW_ARTIST_COLOR
			label_color = app_constants.GRID_VIEW_LABEL_COLOR
			# Enable this to see the defining box
			#painter.drawRect(option.rect)
			# define font size
			if 20 > len(title) > 15:
				title_size = "font-size:{}px;".format(self.font_size)
			elif 30 > len(title) > 20:
				title_size = "font-size:{}px;".format(self.font_size-1)
			elif 40 > len(title) >= 30:
				title_size = "font-size:{}px;".format(self.font_size-2)
			elif 50 > len(title) >= 40:
				title_size = "font-size:{}px;".format(self.font_size-3)
			elif len(title) >= 50:
				title_size = "font-size:{}px;".format(self.font_size-4)
			else:
				title_size = "font-size:{}px;".format(self.font_size)

			if 30 > len(artist) > 20:
				artist_size = "font-size:{}px;".format(self.font_size)
			elif 40 > len(artist) >= 30:
				artist_size = "font-size:{}px;".format(self.font_size-1)
			elif len(artist) >= 40:
				artist_size = "font-size:{}px;".format(self.font_size-2)
			else:
				artist_size = "font-size:{}px;".format(self.font_size)

			#painter.setPen(QPen(Qt.NoPen))
			#option.rect = option.rect.adjusted(11, 10, 0, 0)
			option.rect.setWidth(self.W)

			option.rect.setHeight(self.H)
			rec = option.rect.getRect()
			x = rec[0]
			y = rec[1]
			w = rec[2]
			h = rec[3]

			text_area = QTextDocument()
			text_area.setDefaultFont(option.font)
			text_area.setHtml("""
			<head>
			<style>
			#area
			{{
				display:flex;
				width:{6}px;
				height:{7}px
			}}
			#title {{
			position:absolute;
			color: {4};
			font-weight:bold;
			{0}
			}}
			#artist {{
			position:absolute;
			color: {5};
			top:20px;
			right:0;
			{1}
			}}
			</style>
			</head>
			<body>
			<div id="area">
			<center>
			<div id="title">{2}
			</div>
			<div id="artist">{3}
			</div>
			</div>
			</center>
			</body>
			""".format(title_size, artist_size, title, artist, title_color, artist_color,
			  130+app_constants.SIZE_FACTOR, 1+app_constants.SIZE_FACTOR))
			text_area.setTextWidth(w)

			#chapter_area = QTextDocument()
			#chapter_area.setDefaultFont(option.font)
			#chapter_area.setHtml("""
			#<font color="black">{}</font>
			#""".format("chapter"))
			#chapter_area.setTextWidth(w)
			def center_img(width):
				new_x = x
				if width < w:
					diff = w - width
					offset = diff//2
					new_x += offset
				return new_x

			def img_too_big(start_x):
				txt_layout = misc.text_layout("Image is too big!", w, self.title_font, self.title_font_m)

				clipping = QRectF(x, y+h//4, w, app_constants.GRIDBOX_LBL_H - 10)
				txt_layout.draw(painter, QPointF(x, y+h//4),
					  clip=clipping)

			# if we can't find a cached image
			pix_cache = QPixmapCache.find(self.key(gallery.profile))
			if isinstance(pix_cache, QPixmap):
				self.image = pix_cache
				img_x = center_img(self.image.width())
				if self.image.width() > w or self.image.height() > h:
					img_too_big(img_x)
				else:
					if self.image.height() < self.image.width(): #to keep aspect ratio
						painter.drawPixmap(QPoint(img_x,y),
								self.image)
					else:
						painter.drawPixmap(QPoint(img_x,y),
								self.image)
			else:
				self.image = QPixmap(gallery.profile)
				img_x = center_img(self.image.width())
				QPixmapCache.insert(self.key(gallery.profile), self.image)
				if self.image.width() > w or self.image.height() > h:
					img_too_big(img_x)
				else:
					if self.image.height() < self.image.width(): #to keep aspect ratio
						painter.drawPixmap(QPoint(img_x,y),
								self.image)
					else:
						painter.drawPixmap(QPoint(img_x,y),
								self.image)

			# draw ribbon type
			painter.save()
			painter.setPen(Qt.NoPen)
			if app_constants.DISPLAY_GALLERY_RIBBON:
				type_ribbon_w = type_ribbon_l = w*0.11
				rib_top_1 = QPointF(x+w-type_ribbon_l-type_ribbon_w, y)
				rib_top_2 = QPointF(x+w-type_ribbon_l, y)
				rib_side_1 = QPointF(x+w, y+type_ribbon_l)
				rib_side_2 = QPointF(x+w, y+type_ribbon_l+type_ribbon_w)
				ribbon_polygon = QPolygonF([rib_top_1, rib_top_2, rib_side_1, rib_side_2])
				ribbon_path = QPainterPath()
				ribbon_path.setFillRule(Qt.WindingFill)
				ribbon_path.addPolygon(ribbon_polygon)
				ribbon_path.closeSubpath()
				painter.setBrush(QBrush(QColor(self._ribbon_color(gallery.type))))
				painter.drawPath(ribbon_path)

			# draw if favourited
			if gallery.fav == 1:
				star_ribbon_w = star_ribbon_l = w*0.08
				rib_top_1 = QPointF(x+star_ribbon_l, y)
				rib_side_1 = QPointF(x, y+star_ribbon_l)
				rib_top_2 = QPointF(x+star_ribbon_l+star_ribbon_w, y)
				rib_side_2 = QPointF(x, y+star_ribbon_l+star_ribbon_w)
				rib_star_mid_1 = QPointF((rib_top_1.x()+rib_side_1.x())/2, (rib_top_1.y()+rib_side_1.y())/2)
				rib_star_factor = star_ribbon_l/4
				rib_star_p1_1 = rib_star_mid_1 + QPointF(rib_star_factor, -rib_star_factor)
				rib_star_p1_2 = rib_star_p1_1 + QPointF(-rib_star_factor, -rib_star_factor)
				rib_star_p1_3 = rib_star_mid_1 + QPointF(-rib_star_factor, rib_star_factor)
				rib_star_p1_4 = rib_star_p1_3 + QPointF(-rib_star_factor, -rib_star_factor)

				crown_1 = QPolygonF([rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3])
				painter.setBrush(QBrush(QColor("yellow")))
				painter.drawPolygon(crown_1)

				ribbon_polygon = QPolygonF([rib_top_1, rib_side_1, rib_side_2, rib_top_2])
				ribbon_path = QPainterPath()
				ribbon_path.setFillRule(Qt.WindingFill)
				ribbon_path.addPolygon(ribbon_polygon)
				ribbon_path.closeSubpath()
				painter.drawPath(ribbon_path)
				#painter.setPen(QColor("#d35400"))
				#painter.drawPolyline(rib_top_1, rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3, rib_side_1)
				#painter.drawLine(rib_top_1, rib_top_2)
				#painter.drawLine(rib_top_2, rib_side_2)
				#painter.drawLine(rib_side_1, rib_side_2)
			painter.restore()
			
			if app_constants._REFRESH_EXTERNAL_VIEWER:
				if app_constants.USE_EXTERNAL_VIEWER:
					self.external_icon = self.file_icons.get_external_file_icon()
				else:
					self.external_icon = self.file_icons.get_default_file_icon()
			
			if gallery.state == self.G_DOWNLOAD:
				painter.save()
				dl_box = QRect(x, y, w, 20)
				painter.setBrush(QBrush(QColor(0,0,0,123)))
				painter.setPen(QColor('white'))
				painter.drawRect(dl_box)
				painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...')
				painter.restore()
			else:
				if app_constants.DISPLAY_GALLERY_TYPE:
					self.type_icon = self.file_icons.get_file_icon(gallery.path)
					if self.type_icon and not self.type_icon.isNull():
						self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16))

				if app_constants.USE_EXTERNAL_PROG_ICO:
					if self.external_icon and not self.external_icon.isNull():
						self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28))

			def draw_text_label(lbl_h):
				#draw the label for text
				painter.save()
				painter.translate(x, y+app_constants.THUMB_H_SIZE)
				box_color = QBrush(QColor(label_color))#QColor(0,0,0,123))
				painter.setBrush(box_color)
				rect = QRect(0, 0, w, lbl_h) #x, y, width, height
				painter.fillRect(rect, box_color)
				painter.restore()
				return rect

			if option.state & QStyle.State_MouseOver or\
			    option.state & QStyle.State_Selected:
				title_layout = misc.text_layout(title, w, self.title_font, self.title_font_m)
				artist_layout = misc.text_layout(artist, w, self.artist_font, self.artist_font_m)
				t_h = title_layout.boundingRect().height()
				a_h = artist_layout.boundingRect().height()

				if app_constants.GALLERY_FONT_ELIDE:
					lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H))
				else:
					lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H)

				clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10)
				painter.setPen(QColor(title_color))
				title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE),
					  clip=clipping)
				painter.setPen(QColor(artist_color))
				artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h),
					   clip=clipping)
				#painter.fillRect(option.rect, QColor)
			else:
				if app_constants.GALLERY_FONT_ELIDE:
					lbl_rect = draw_text_label(self.text_label_h)
				else:
					lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H)
				# draw text
				painter.save()
				alignment = QTextOption(Qt.AlignCenter)
				alignment.setUseDesignMetrics(True)
				title_rect = QRectF(0,0,w, self.title_font_m.height())
				artist_rect = QRectF(0,self.artist_font_m.height(),w,
						 self.artist_font_m.height())
				painter.translate(x, y+app_constants.THUMB_H_SIZE)
				if app_constants.GALLERY_FONT_ELIDE:
					painter.setFont(self.title_font)
					painter.setPen(QColor(title_color))
					painter.drawText(title_rect,
							 self.title_font_m.elidedText(title, Qt.ElideRight, w-10),
							 alignment)
				
					painter.setPen(QColor(artist_color))
					painter.setFont(self.artist_font)
					alignment.setWrapMode(QTextOption.NoWrap)
					painter.drawText(artist_rect,
								self.title_font_m.elidedText(artist, Qt.ElideRight, w-10),
								alignment)
				else:
					text_area.setDefaultFont(QFont(self.font_name))
					text_area.drawContents(painter)
				##painter.resetTransform()
				painter.restore()

			if option.state & QStyle.State_Selected:
				painter.save()
				selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE)
				painter.setPen(Qt.NoPen)
				painter.setBrush(QBrush(QColor(164,164,164,120)))
				painter.drawRoundedRect(selected_rect, 5, 5)
				#painter.fillRect(selected_rect, QColor(164,164,164,120))
				painter.restore()

			if gallery.dead_link:
				painter.save()
				selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE)
				painter.setPen(Qt.NoPen)
				painter.setBrush(QBrush(QColor(255,0,0,120)))
				p_path = QPainterPath()
				p_path.setFillRule(Qt.WindingFill)
				p_path.addRoundedRect(selected_rect, 5,5)
				p_path.addRect(x,y, 20, 20)
				p_path.addRect(x+w-20,y, 20, 20)
				painter.drawPath(p_path.simplified())
				painter.setPen(QColor("white"))
				txt_layout = misc.text_layout("Cannot find gallery source!", w, self.title_font, self.title_font_m)
				txt_layout.draw(painter, QPointF(x, y+h*0.3))
				painter.restore()

			if app_constants.DEBUG:
				painter.save()
				painter.setBrush(QBrush(QColor("red")))
				painter.setPen(QColor("white"))
				txt_l = self.title_font_m.width(str(gallery.id))
				painter.drawRect(x, y+40, txt_l*2, self.title_font_m.height())
				painter.drawText(x+1, y+51, str(gallery.id))
				painter.restore()
			if option.state & QStyle.State_Selected:
				painter.setPen(QPen(option.palette.highlightedText().color()))
		else:
			super().paint(painter, option, index)
示例#50
0
class InstanceOfEdge(AbstractEdge):
    """
    This class implements the InstanceOf edge.
    """
    item = Item.InstanceOfEdge

    def __init__(self, **kwargs):
        """
        Initialize the InstanceOf edge.
        """
        super().__init__(**kwargs)
        self.label = Label('instanceOf', centered=True, parent=self)

    ####################################################################################################################
    #                                                                                                                  #
    #   INTERFACE                                                                                                      #
    #                                                                                                                  #
    ####################################################################################################################

    def copy(self, scene):
        """
        Create a copy of the current edge.
        :type scene: DiagramScene
        """
        kwargs = {
            'id': self.id,
            'source': self.source,
            'target': self.target,
            'breakpoints': self.breakpoints[:],
        }
        return scene.factory.create(item=self.item, scene=scene, **kwargs)

    @staticmethod
    def createHead(pos1, angle, size):
        """
        Create the head polygon.
        :type pos1: QPointF
        :type angle: float
        :type size: int
        :rtype: QPolygonF
        """
        rad = radians(angle)
        pos2 = pos1 - QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size)
        pos3 = pos1 - QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size)
        return QPolygonF([pos1, pos2, pos3])

    def updateLabel(self, points):
        """
        Update the label text position.
        :type points: T <= tuple | list
        """
        self.label.updatePos(points)

    ####################################################################################################################
    #                                                                                                                  #
    #   GEOMETRY                                                                                                       #
    #                                                                                                                  #
    ####################################################################################################################

    def boundingRect(self):
        """
        Returns the shape bounding rect.
        :rtype: QRectF
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        for shape in self.handles:
            path.addEllipse(shape)
        for shape in self.anchors.values():
            path.addEllipse(shape)

        return path.controlPointRect()

    def painterPath(self):
        """
        Returns the current shape as QPainterPath (used for collision detection).
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.path)
        path.addPolygon(self.head)

        return path

    def shape(self):
        """
        Returns the shape of this item as a QPainterPath in local coordinates.
        :rtype: QPainterPath
        """
        path = QPainterPath()
        path.addPath(self.selection)
        path.addPolygon(self.head)

        if self.isSelected():
            for shape in self.handles:
                path.addEllipse(shape)
            for shape in self.anchors.values():
                path.addEllipse(shape)

        return path

    ####################################################################################################################
    #                                                                                                                  #
    #   GEOMETRY UPDATE                                                                                                #
    #                                                                                                                  #
    ####################################################################################################################

    def updateEdge(self, target=None):
        """
        Update the edge painter path and the selection polygon.
        :type target: QPointF
        """
        boxSize = self.selectionSize
        headSize = self.headSize
        sourceNode = self.source
        targetNode = self.target
        sourcePos = sourceNode.anchor(self)
        targetPos = target or targetNode.anchor(self)

        self.prepareGeometryChange()

        self.updateAnchors()
        self.updateBreakPoints()
        self.updateZValue()

        createSelectionArea = self.createSelectionArea
        createHead = self.createHead

        ################################################################################################################
        #                                                                                                              #
        #   UPDATE EDGE PATH, SELECTION BOX AND HEAD                                                                   #
        #                                                                                                              #
        ################################################################################################################

        # get the list of visible subpaths for this edge
        collection = self.computePath(sourceNode, targetNode, [sourcePos] + self.breakpoints + [targetPos])

        self.path = QPainterPath()
        self.selection = QPainterPath()
        self.head = QPolygonF()

        points = [] # will store all the points defining the edge not to recompute the path to update the label
        append = points.append  # keep this shortcut and the one below since it saves a lot of computation
        extend = points.extend  # more: http://blog.cdleary.com/2010/04/efficiency-of-list-comprehensions/

        if len(collection) == 1:

            subpath = collection[0]
            p1 = sourceNode.intersection(subpath)
            p2 = targetNode.intersection(subpath) if targetNode else subpath.p2()
            if p1 is not None and p2 is not None:
                self.path.moveTo(p1)
                self.path.lineTo(p2)
                self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize))
                self.head = createHead(p2, subpath.angle(), headSize)
                extend((p1, p2))

        elif len(collection) > 1:

            subpath1 = collection[0]
            subpathN = collection[-1]
            p11 = sourceNode.intersection(subpath1)
            p22 = targetNode.intersection(subpathN)

            if p11 and p22:

                p12 = subpath1.p2()
                p21 = subpathN.p1()

                self.path.moveTo(p11)
                self.path.lineTo(p12)
                self.selection.addPolygon(createSelectionArea(p11, p12, subpath1.angle(), boxSize))
                extend((p11, p12))

                for subpath in collection[1:-1]:
                    p1 = subpath.p1()
                    p2 = subpath.p2()
                    self.path.moveTo(p1)
                    self.path.lineTo(p2)
                    self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize))
                    append(p2)

                self.path.moveTo(p21)
                self.path.lineTo(p22)
                self.selection.addPolygon(createSelectionArea(p21, p22, subpathN.angle(), boxSize))
                append(p22)

                self.head = createHead(p22, subpathN.angle(), headSize)

        self.updateLabel(points)
        self.updateBrush(selected=self.isSelected(), visible=self.canDraw())

    ####################################################################################################################
    #                                                                                                                  #
    #   DRAWING                                                                                                        #
    #                                                                                                                  #
    ####################################################################################################################

    @classmethod
    def image(cls, **kwargs):
        """
        Returns an image suitable for the palette.
        :rtype: QPixmap
        """
        # INITIALIZATION
        pixmap = QPixmap(kwargs['w'], kwargs['h'])
        pixmap.fill(Qt.transparent)
        painter = QPainter(pixmap)
        # INITIALIZE EDGE LINE
        pp1 = QPointF(((kwargs['w'] - 52) / 2), kwargs['h'] / 2)
        pp2 = QPointF(((kwargs['w'] - 52) / 2) + 52 - 2, kwargs['h'] / 2)
        line = QLineF(pp1, pp2)
        # CALCULATE HEAD COORDINATES
        angle = radians(line.angle())
        p1 = QPointF(line.p2().x() + 2, line.p2().y())
        p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8)
        p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8)
        # INITIALIZE EDGE HEAD
        head = QPolygonF([p1, p2, p3])
        # DRAW THE POLYGON
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        # DRAW HEAD
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.setBrush(QColor(0, 0, 0))
        painter.drawPolygon(head)
        # DRAW THE TEXT ON TOP OF THE EDGE
        space = 2 if Platform.identify() is Platform.Darwin else 0
        painter.setFont(Font('Arial', 9, Font.Light))
        painter.drawText(pp1.x() + space, (kwargs['h'] / 2) - 4, 'instanceOf')

        return pixmap

    def paint(self, painter, option, widget=None):
        """
        Paint the edge in the diagram scene.
        :type painter: QPainter
        :type option: QStyleOptionGraphicsItem
        :type widget: QWidget
        """
        # SET THE RECT THAT NEEDS TO BE REPAINTED
        painter.setClipRect(option.exposedRect)
        # SELECTION AREA
        painter.setRenderHint(QPainter.Antialiasing)
        painter.fillPath(self.selection, self.selectionBrush)
        # EDGE LINE
        painter.setPen(self.pen)
        painter.drawPath(self.path)
        # HEAD POLYGON
        painter.setPen(self.headPen)
        painter.setBrush(self.headBrush)
        painter.drawPolygon(self.head)
        # BREAKPOINTS AND ANCHOR POINTS
        painter.setPen(self.handlePen)
        painter.setBrush(self.handleBrush)
        for shape in self.handles:
            painter.drawEllipse(shape)
        for shape in self.anchors.values():
            painter.drawEllipse(shape)