Beispiel #1
0
    def __drawPoint(self, x, y, index):
        #横线
        line1 = QGraphicsLineItem()
        line1.setPen(self.pen)
        line1.setLine(x - self.lineRadius, y, x + self.lineRadius, y)

        #竖线
        line2 = QGraphicsLineItem()
        line2.setPen(self.pen)
        line2.setLine(x, y - self.lineRadius, x, y + self.lineRadius)

        #文字说明
        text = QGraphicsTextItem()
        text.setDefaultTextColor(Qt.blue)
        text.setFont(self.font)

        text.setPlainText(self.pointsName[index])
        text.setPos(x, y)

        #放到组中
        pointGroup = QGraphicsItemGroup()
        pointGroup.addToGroup(line1)
        pointGroup.addToGroup(line2)
        pointGroup.addToGroup(text)

        #显示
        if self.pointsItem[index] is not None:
            self.scene.removeItem(self.pointsItem[index])

        #保存到字典
        self.pointsItem[index] = pointGroup
        #显示该点
        self.scene.addItem(self.pointsItem[index])
Beispiel #2
0
    def refresh(self):
        if not self.items():
            return
        super().refresh()
        
        for i in self.items():
            if isinstance(i, QGraphicsLineItem):
                self.removeItem(i)


        hull = self.hull_method(self.point_model.points)
        pts = hull + [hull[0]]


        point_items = list(filter(lambda i: isinstance(i, PointGraphicsItem), self.items()))
        for p in point_items:
            p.setBrush(Qt.blue)

        min_point = min(point_items, key=lambda p:p.x())
        min_point.setBrush(Qt.green)

        for i in range(len(pts)-1):
            dx, dy = pts[i+1].x - pts[i].x, pts[i+1].y - pts[i].y
            line = QGraphicsLineItem(pts[i+1].x, pts[i+1].y, pts[i+1].x+dx, pts[i+1].y+dy)
            pen = QPen()
            pen.setStyle(Qt.DashLine)
            line.setPen(pen)
            line.setZValue(-2)
            self.addItem(line)
            h_line = QGraphicsLineItem(pts[i].x, pts[i].y, pts[i+1].x, pts[i+1].y)
            h_line.setPen(Qt.red)
            h_line.setZValue(-1)


        self.enumeratePoints()
 def add_clearance_graph(self):
     print("-----------------------------------------")
     horizontal_clearance = self.clearance_analysis.horizontal_clearance
     x_init = self.graph_zero[0] + self.line_extend
     y_init = self.graph_zero[1]
     for i in range(len(horizontal_clearance)):
         clearance_points = horizontal_clearance[i]
         x = x_init + i * self.dimension_analysis.section_distance * self.length_multiplier
         left = -self.dimension_analysis.domain_length
         right = self.dimension_analysis.domain_length
         if clearance_points[0]:
             left = clearance_points[0]
         if clearance_points[1]:
             right = clearance_points[1]
         clearance = right - left
         y_top = y_init + left * self.height_multiplier
         y_bottom = y_init + right * self.height_multiplier
         pen_red = QPen()
         red = Color.create_qcolor_from_rgb_tuple(Color.red)
         pen_red.setColor(red)
         pen_green = QPen()
         green = Color.create_qcolor_from_rgb_tuple(Color.green)
         pen_green.setColor(green)
         line = QGraphicsLineItem(x, y_top, x, y_bottom)
         if clearance < self.min_horizontal_clearance:
             line.setPen(pen_red)
         else:
             line.setPen(pen_green)
         self.addToGroup(line)
     pass
Beispiel #4
0
 def draw_curve(self):
     curve = QLineF(self.origin_pos, self.current_pos)
     curve_item = QGraphicsLineItem(curve)
     curve_item.setPen(self.pen)
     curve_item.setFlag(QGraphicsItem.ItemIsMovable, True)
     self.addItem(curve_item)
     self.origin_pos = self.current_pos
Beispiel #5
0
 def create_fromDB(self,pos_list=[],obj_type=""):      
     if obj_type =="rois":
         num_rois = len(pos_list)
         for i in range(num_rois):
             points = pos_list[i]
             rect=QGraphicsRectItem()
             rect.setPen(QPen(Qt.green))
             rect.setRect(points[0],points[1],points[2],points[3])
             self.rectgroup.addToGroup(rect)
         self.scene.addItem(self.rectgroup)
     elif obj_type =="vector1":
         num_vec = len(pos_list)
         for i in range(num_vec):
             points = pos_list[i]
             vec=QGraphicsLineItem()
             vec.setPen(QPen(Qt.green))
             vec.setLine(points[0],points[1],points[2],points[3])
             self.linegroup.addToGroup(vec)
         self.scene.addItem(self.linegroup)
     elif obj_type =="vector2":
         num_vec = len(pos_list)
         for i in range(num_vec):
             points = pos_list[i]
             vec=QGraphicsLineItem()
             vec.setPen(QPen(Qt.green))
             vec.setLine(points[0],points[1],points[2],points[3])
             self.linegroup2.addToGroup(vec)
         self.scene.addItem(self.linegroup2)
Beispiel #6
0
    def add_connecting_line(self, atom1, atom2):

        if atom1.y() > atom2.y():
            y1 = atom1.y() + (atom1.boundingRect().height() * .5)
            y2 = atom2.y() + (atom2.boundingRect().height() * .5)

        elif atom1.y() < atom2.y():
            y1 = atom1.y() + (atom1.boundingRect().height() * .5)
            y2 = atom2.y() + (atom2.boundingRect().height() * .5)

        else:
            y1 = atom1.y() + (atom1.boundingRect().height() * 0.5)
            y2 = atom2.y() + (atom2.boundingRect().height() * 0.5)

        if atom1.x() > atom2.x():
            x1 = atom1.x()
            x2 = atom2.x() + atom2.boundingRect().width()

        elif atom1.x() < atom2.x():
            x1 = atom1.x() + atom1.boundingRect().width()
            x2 = atom2.x()

        else:
            x1 = atom1.x() + (atom1.boundingRect().width() / 2)
            x2 = atom2.x() + (atom1.boundingRect().width() / 2)

        new_line = QGraphicsLineItem(x1, y1, x2, y2)
        pen = QtGui.QPen()
        pen.setColor(QtGui.QColor("#FAFAF7"))
        pen.setCosmetic(True)
        pen.setWidth(1)
        new_line.setPen(pen)
        self.scene.addItem(new_line)
Beispiel #7
0
 def add_Line(self, l):
     assert isinstance(l, Line)
     line = QGraphicsLineItem(l.End_p[0].x, l.End_p[0].y, l.End_p[1].x,
                              l.End_p[1].y)
     line.setPen(self.linePen)
     self.Line_list.append(line)
     self.gscene.addItem(line)
Beispiel #8
0
class RSegment(QObject):
    def __init__(self, x1, y1, x2, y2, color, line_width):
        self._x1 = x1
        self._y1 = y1
        self._x2 = x2
        self._y2 = y2
        self._pos = QPointF(x1, y1)
        super().__init__()
        self.line = QGraphicsLineItem()
        self.line.setLine(x1, y1, x2, y2)
        pen = QPen()
        pen.setWidthF(line_width)
        pen.setColor(color)
        self.line.setPen(pen)

    def x(self):
        return self._pos.x()

    def y(self):
        return self._pos.y()

    @pyqtProperty(QPointF)
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, value):
        delta_x = value.x() - self._pos.x()
        delta_y = value.y() - self._pos.y()
        self._x1 = self._x1 + delta_x
        self._y1 = self._y1 + delta_y
        self._x2 = self._x2 + delta_x
        self._y2 = self._y2 + delta_y
        self.line.setLine(self._x1, self._y1, self._x2, self._y2)
        self._pos = value
Beispiel #9
0
    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:

            downPos = event.buttonDownPos(Qt.LeftButton)
            if not self.__tmpLine and self.__dragStartItem and \
                    (downPos - event.pos()).manhattanLength() > \
                        QApplication.instance().startDragDistance():
                # Start a line drag
                line = QGraphicsLineItem(self)
                start = self.__dragStartItem.boundingRect().center()
                start = self.mapFromItem(self.__dragStartItem, start)
                line.setLine(start.x(), start.y(),
                             event.pos().x(),
                             event.pos().y())

                pen = QPen(Qt.black, 4)
                pen.setCapStyle(Qt.RoundCap)
                line.setPen(pen)
                line.show()

                self.__tmpLine = line

            if self.__tmpLine:
                # Update the temp line
                line = self.__tmpLine.line()
                line.setP2(event.pos())
                self.__tmpLine.setLine(line)

        QGraphicsWidget.mouseMoveEvent(self, event)
Beispiel #10
0
    def mouseMoveEvent(self, event, image_item):
        if self._aiming:
            if self._helpLines is not None and self._helpLines.scene(
            ) is not None:
                self._scene.removeItem(self._helpLines)

            self._helpLines = QGraphicsItemGroup()
            group = self._helpLines

            verticalHelpLine = QGraphicsLineItem(event.scenePos().x(), 0,
                                                 event.scenePos().x(),
                                                 self._scene.height())
            horizontalHelpLine = QGraphicsLineItem(0,
                                                   event.scenePos().y(),
                                                   self._scene.width(),
                                                   event.scenePos().y())

            horizontalHelpLine.setPen(self._helpLinesPen)
            verticalHelpLine.setPen(self._helpLinesPen)

            group.addToGroup(verticalHelpLine)
            group.addToGroup(horizontalHelpLine)

            self._scene.addItem(self._helpLines)
        else:
            if self._item is not None:
                assert self._init_pos is not None
                rect = QRectF(self._init_pos, event.scenePos()).normalized()
                self._item.setRect(rect)

        event.accept()
Beispiel #11
0
 def importSVG(self, filepath, view):
     
     try:
         doc = minidom.parse(filepath)
     except (ExpatError, IsADirectoryError):
         # xml file is broken: we can't import it
         pass
     else:
     
         lines = doc.getElementsByTagName("line")
         for line in lines:
             x1 = line.getAttribute("x1")
             y1 = line.getAttribute("y1")
             x2 = line.getAttribute("x2")
             y2 = line.getAttribute("y2")
             width = line.getAttribute("width")
             
             lineItem = QGraphicsLineItem(float(x1), float(y1), float(x2), float(y2))
             lineItem.setPen(QPen(view.colour, view.penRadius, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
             view.scene().addItem(lineItem)
             
         ellipses = doc.getElementsByTagName("ellipse")
         for ellipse in ellipses:
             cx = ellipse.getAttribute("cx")
             cy = ellipse.getAttribute("cy")
             rx = ellipse.getAttribute("rx")
             ry = ellipse.getAttribute("ry")
             width = ellipse.getAttribute("width")
             
             ellipseItem = QGraphicsEllipseItem(float(cx)-float(rx), float(cy)-float(ry), float(rx)*2, float(ry)*2)
             ellipseItem.setPen(QPen(view.colour, QtCore.Qt.SolidPattern))
             ellipseItem.setBrush(view.colour)
             
             view.scene().addItem(ellipseItem)
Beispiel #12
0
class WayPoint:
    def __init__(self, **kwargs):
        super().__init__()
        self.location = MapPoint()
        self.__dict__.update(kwargs)

        self.pixmap = QGraphicsPixmapItem(
            QPixmap('HOME_DIR + /nparse/data/maps/waypoint.png'))
        self.pixmap.setOffset(-10, -20)

        self.line = QGraphicsLineItem(0.0, 0.0, self.location.x,
                                      self.location.y)
        self.line.setPen(QPen(Qt.green, 1, Qt.DashLine))
        self.line.setVisible(False)

        self.pixmap.setZValue(5)
        self.line.setZValue(4)

        self.pixmap.setPos(self.location.x, self.location.y)

    def update_(self, scale, location=None):
        self.pixmap.setScale(scale)
        if location:
            line = self.line.line()
            line.setP1(QPointF(location.x, location.y))
            self.line.setLine(line)

            pen = self.line.pen()
            pen.setWidth(1 / scale)
            self.line.setPen(pen)

            self.line.setVisible(True)
    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x, y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(
            QPen(QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX, oldY), QSize(1, 1))
        #grow bounding box
        self.bb.setLeft(
            min(self.bb.left(), max(0, x - self.brushSize // 2 - 1)))
        self.bb.setRight(
            max(self.bb.right(),
                min(self.sliceRect[0] - 1, x + self.brushSize // 2 + 1)))
        self.bb.setTop(min(self.bb.top(), max(0, y - self.brushSize // 2 - 1)))
        self.bb.setBottom(
            max(self.bb.bottom(),
                min(self.sliceRect[1] - 1, y + self.brushSize // 2 + 1)))

        #update/move position
        self.pos = pos
 def drawObstacleWarnings(self, result):
     for item in self.obstacleMarkerShapes:
         self.augmentedRealityScene.removeItem(item)
     self.obstacleMarkerShapes.clear()
     shape0 = QGraphicsEllipseItem(-self.AugmentedRealityPanel.height() / 2,
                                   -self.AugmentedRealityPanel.height() / 2, self.AugmentedRealityPanel.height(),
                                   self.AugmentedRealityPanel.height())
     shape0.setPen(QPen(self.black))
     shape0.setOpacity(0.01)
     self.augmentedRealityScene.addItem(shape0)
     self.obstacleMarkerShapes.append(shape0)
     if (self.ObstacleWarningCB.isChecked()):
         markersToShow = np.zeros(self.numberOfObstacleGroupings)
         startAngle = result.angle_min
         angleIncrement = result.angle_increment
         AngleCutOff = 2 * np.pi / self.numberOfObstacleGroupings
         offset = np.pi/2
         for point in range(0, len(result.ranges)):
             if result.ranges[point]<=self.obstacleWarningDistance:
                 angle = startAngle + angleIncrement*point
                 directionSector = int(angle/AngleCutOff)
                 markersToShow[directionSector]=1
         for marker in range(0, self.numberOfObstacleGroupings):
             if(markersToShow[marker]):
                 shape = QGraphicsLineItem(-self.AugmentedRealityPanel.height()*0.98/2*math.cos(marker*AngleCutOff+offset),-self.AugmentedRealityPanel.height()*0.98/2*math.sin(marker*AngleCutOff+offset), -self.AugmentedRealityPanel.height()*0.98/2*math.cos((marker+1)*AngleCutOff+offset),-self.AugmentedRealityPanel.height()*0.98/2*math.sin((marker+1)*AngleCutOff+offset))
                 shape.setPen(QPen(self.red, 5))
                 self.augmentedRealityScene.addItem(shape)
                 self.obstacleMarkerShapes.append(shape)
     self.AugmentedRealityPanel.centerOn(QPoint(0, 0))
Beispiel #15
0
 def drawForever(self):
     line = QLineF(self.originPos, self.currentPos)
     line_item = QGraphicsLineItem(line)
     line_item.setPen(self.pen)
     line_item.setFlag(QGraphicsItem.ItemIsMovable, True)
     self.addItem(line_item)
     self.originPos = self.currentPos
Beispiel #16
0
 def drawSegment(self):
     line = QLineF(self.originPos, self.currentPos)
     line_item = QGraphicsLineItem(line)
     line_item.setPen(self.pen)
     line_item.setFlag(QGraphicsItem.ItemIsMovable, True)
     if len(self.items()) > 0:
         self.clearLastItem()
     self.addItem(line_item)
Beispiel #17
0
 def draw_line(self):
     line = QLineF(self.origin_pos, self.current_pos)
     line_item = QGraphicsLineItem(line)
     line_item.setPen(self.pen)
     line_item.setFlag(QGraphicsItem.ItemIsMovable, True)
     if len(self.items()) > 0:
         self.clear_last_item()
     self.addItem(line_item)
Beispiel #18
0
    def distance_to(self, item):

        distance = QLineF(QPointF(self.pos().x() + 25,
                                  self.pos().y() + 25), item.pos())
        line = QGraphicsLineItem(distance)
        line.setPen(QPen(Qt.red))
        #        self.scene().addItem(line)
        return distance.length()
Beispiel #19
0
    def draw_line(self):
        line_pen = QPen(Qt.black, 2)
        item = QGraphicsLineItem(0, self.h, self.w, self.h)
        item.setPen(line_pen)
        self.scene.addItem(item)

        item = QGraphicsLineItem(self.w, 0, self.w, self.h)
        item.setPen(line_pen)
        self.scene.addItem(item)
Beispiel #20
0
 def add_graphics_line_item(self, line):
     line_item = QGraphicsLineItem(line)
     line_item.setPen(self.pen)
     line_item.setZValue(-1)
     scene = self.model.gui.scene
     scene.addItem(line_item)
     pair = (line, line_item)
     self.line_pairs.append(pair)
     return pair
Beispiel #21
0
 def drawLinesFromOriginToPoints(self):
     points = self.algorithm.stageResults[1]
     for p in points:
         line = QGraphicsLineItem(self.originItem.x(), self.originItem.y(),
                                  p.x, p.y)
         pen = QPen()
         pen.setStyle(Qt.DashLine)
         line.setPen(pen)
         line.setZValue(-1)
         self.addItem(line)
Beispiel #22
0
 def drawLrLine(self):
     leftmost = list(filter(lambda i: i.point == self.algorithm.stageResults[0][0], self.items()))[0]
     rightmost = list(filter(lambda i: i.point == self.algorithm.stageResults[0][1], self.items()))[0]
     leftmost.setBrush(Qt.red)
     rightmost.setBrush(Qt.red)
     
     lr_line = QGraphicsLineItem(leftmost.x(), leftmost.y(), rightmost.x(), rightmost.y())
     lr_line.setPen(Qt.red)
     lr_line.setZValue(-1)
     self.addItem(lr_line)
Beispiel #23
0
    def updateCurve(self, name, color=Qt.black):
        # if name in self.curveObjs:
        #     curveitem = self.curveObjs[name]
        # else:
        #     curveitem = QGraphicsPathItem()
        #     self.scene.addItem(curveitem)
        # # path=curveitem.path()
        # path = QPainterPath()
        #
        # pointItems = self.curvePointObjs[name]
        # if len(pointItems) > 0:
        #     path.moveTo(pointItems[0].pos())
        # for pointitem in pointItems[1:]:
        #     path.lineTo(pointitem.pos())
        # curveitem.setPath(path)
        # curveitem.update(curveitem.boundingRect())
        # curveitem.prepareGeometryChange()
        # self.scene.update()
        # self.viewport().repaint()
        # self.viewport().update()

        if not isinstance(name, str):
            return
        if name not in self.pointObjs:
            return

        lastitems = []
        if name in self.curveObjs:
            lastitems = self.curveObjs[name]
            if not isinstance(lastitems, list):
                lastitems = []

        if name in self.pointObjs:
            pointItems = self.pointObjs[name]
        else:
            pointItems = []
        points = []
        for ptitem in pointItems:
            points.append(ptitem.pos())

        self.curveObjs[name] = []
        if len(points) > 1:
            for i in range(1, len(points)):
                l = QGraphicsLineItem(points[i - 1].x(), points[i - 1].y(),
                                      points[i].x(), points[i].y())
                l.setPen(color)
                l.setZValue(10)
                # l.setFlag(QGraphicsItem.ItemIsSelectable)
                self.curveObjs[name].append(l)
                self.scene.addItem(l)

        for line in lastitems:
            self.scene.removeItem(line)

        self.updateCurvePoints(name)
Beispiel #24
0
 def updateGraphicsLineItem(line: QGraphicsLineItem, lineF: QLineF = None, pen: QPen = None):
     """
     更新线 QGraphicsLineItem属性
     :param line: QGraphicsLineItem
     :param lineF: 线的坐标大小
     :param pen: 画笔
     """
     if lineF:
         line.setLine(lineF)
     if pen:
         line.setPen(pen)
 def add_dummy_line_for_margin(self):
     height = self.scene.height()
     width = self.scene.width()
     pen = QPen()
     pen.setStyle(Qt.NoPen)
     dummy_line_a= QGraphicsLineItem(0, height, 0, height + 100)
     dummy_line_b = QGraphicsLineItem(width, 0, width + 100, 0)
     dummy_line_a.setPen(pen)
     dummy_line_b.setPen(pen)
     self.scene.addItem(dummy_line_a)
     self.scene.addItem(dummy_line_b)
Beispiel #26
0
 def fire(self):
     arrow = Arrow()
     arrow.setPos(self.x(), self.y())
     attack_line = QLineF(QPointF(self.x() + 25,
                                  self.y() + 25), self.attack_destination)
     line = QGraphicsLineItem(attack_line)
     line.setPen(QPen(Qt.blue))
     #       self.scene().addItem(line)
     attack_angle = -1 * attack_line.angle(
     )  # Multiplied by -1 because the angle is given in counter clockwise direction
     arrow.setRotation(attack_angle)
     self.scene().addItem(arrow)
Beispiel #27
0
class CrosshairGraphicsItem(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.horizontal_line = QGraphicsLineItem()
        self.vertical_line = QGraphicsLineItem()

        self.horizontal_line.setLine(0, 1080 / 2, 1920, 1080 / 2)
        self.vertical_line.setLine(1920 / 2, 0, 1920 / 2, 1080)

        self.pen = QPen(Qt.white)
        self.horizontal_line.setPen(self.pen)
        self.vertical_line.setPen(self.pen)
Beispiel #28
0
    def __init__(self, parent, color):
        super().__init__(None)

        self.color = QColor(color)
        self.pen = QPen()
        self.pen.setColor(self.color)
        self.lines = []
        self.offset_x = 10

        for x in range(self.offset_x, 500 + self.offset_x):
            line = QGraphicsLineItem(self)
            line.setLine(x, 20 + 200, x + 1, 20 + 200)
            line.setPen(self.pen)
            self.lines.append(line)
 def create_axis(self):
     bounding_end = abs(self.dimension_analysis.bounding_rect[3])
     bounding_start = abs(self.dimension_analysis.bounding_rect[2])
     pen = QPen()
     pen.setWidthF(0.5)
     # horizontal line
     self.graph_zero[0] = self.position[0] + self.margin - self.line_extend
     self.graph_zero[1] = self.position[1] + bounding_start * self.height_multiplier + self.margin
     self.graph_end[0] = self.graph_zero[0] + self.content_width + self.line_extend
     self.graph_end[1] = self.graph_zero[1]
     line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], self.graph_zero[1], self.graph_end[0], self.graph_end[1])
     line_item_horizontal.setPen(pen)
     self.addToGroup(line_item_horizontal)
     center = (self.graph_zero[0] + self.line_extend), self.graph_zero[1]
     y_top = center[1] - (bounding_start*self.height_multiplier)
     y_bottom = center[1]+(bounding_end*self.height_multiplier)
     line_item_vertical = QGraphicsLineItem(center[0], y_top, center[0], y_bottom)
     line_item_vertical.setPen(pen)
     self.addToGroup(line_item_vertical)
     pen_thin = QPen()
     pen_thin.setWidthF(0.2)
     start_graph = center[1] - 10
     while start_graph > center[1] - bounding_start * self.height_multiplier:
         line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], start_graph, self.graph_end[0], start_graph)
         line_item_horizontal.setPen(pen_thin)
         line_item_horizontal.setZValue(-0.5)
         self.addToGroup(line_item_horizontal)
         start_graph -= 10
     start_graph = center[1] + 10
     while start_graph < center[1] + bounding_end * self.height_multiplier:
         line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], start_graph, self.graph_end[0], start_graph)
         line_item_horizontal.setPen(pen_thin)
         line_item_horizontal.setZValue(-0.5)
         self.addToGroup(line_item_horizontal)
         start_graph += 10
Beispiel #30
0
    def drawHlrLines(self):
        hlr = self.algorithm.stageResults[1]
        for h, l, r in hlr:
            pen = QPen()
            pen.setStyle(Qt.PenStyle.DashLine)

            lh_line = QGraphicsLineItem(l.x, l.y, h.x, h.y)
            lh_line.setPen(pen)
            lh_line.setZValue(-1)
            rh_line = QGraphicsLineItem(r.x, r.y, h.x, h.y)
            rh_line.setPen(pen)
            rh_line.setZValue(-1)
            self.addItem(lh_line)
            self.addItem(rh_line)
Beispiel #31
0
    def __init__(self, *args, **kwargs):
        self.width = kwargs.pop('width', 1)
        self.height = kwargs.pop('height', 1)
        self.pickup_point = kwargs.pop('pickup_point', False)
        self.draw_corners = kwargs.pop('draw_corners', False)
        self.scale = kwargs.pop('scale', 1)

        super().__init__(*args, **kwargs)

        self._lines = []
        self._linesF = []
        self._points = []
        self._pointsF = []

        self.pickupPointX = 50
        self.pickupPointY = 50

        self._circleDia = 2.0
        self._linePen = QPen(QColor(135, 208, 80))
        self._linePen.setCapStyle(Qt.RoundCap)
        self._circlePen = QPen(QColor(66, 66, 66))
        self._pickupPen = QPen(QColor(135, 66, 66))

        self._linePen.setCapStyle(Qt.RoundCap)
        self._circlePen.setCapStyle(Qt.RoundCap)
        self._pickupPen.setCapStyle(Qt.RoundCap)

        self._linePen.setWidth(1)
        self._circlePen.setWidth(2)
        self._pickupPen.setWidth(2)

        for i in range(4):
            l = QGraphicsLineItem()
            l.setPen(self._linePen)
            self._lines.append(l)
            self._linesF.append(QLineF())

        for i in range(4):
            self._pointsF.append(QPointF(0.0, 0.0))

        if self.draw_corners:
            for i in range(4):
                e = QGraphicsCircleItem(diameter=self._circleDia)
                e.setPen(self._circlePen)
                self._points.append(e)

        if self.pickup_point:
            self._pickupPointF = QPointF()
            self._pickupPoint = QGraphicsCircleItem(diameter=self._circleDia)
            self._pickupPoint.setPen(self._pickupPen)
Beispiel #32
0
 def generateData(self, canvas, lines, params):
     scene = QGraphicsScene()
     scene.setSceneRect(canvas)
     group = scene.createItemGroup([])
     for line in lines:
         clone = QGraphicsLineItem(line)
         clone.setLine(line.line())
         clone.setPen(line.pen())
         scene.addItem(clone)
         group.addToGroup(clone)
     pixmaps = []
     for i in xrange(params.count):
         pixmaps.append(self.generateRandom(scene, group, canvas, params))
     return pixmaps
Beispiel #33
0
class RSegment(QObject):
    def __init__(self, x1, y1, l, a, color, line_width):
        self._point_radius = 3
        self._angle = a
        self._length = l
        self._x1 = x1
        self._y1 = y1
        self._x2 = x1 + self._length * math.cos(self._angle)
        self._y2 = y1 + self._length * math.sin(self._angle)
        self._pos = QVector3D(x1, y1, self._angle)
        super().__init__()
        self.line = QGraphicsLineItem()
        self.rect = QRectF(x1 - self._point_radius, y1 - self._point_radius,
                           2 * self._point_radius, 2 * self._point_radius)
        self.point = QGraphicsEllipseItem()
        self.point.setRect(self.rect)
        self.line.setLine(self._x1, self._y1, self._x2, self._y2)
        pen = QPen()
        pen.setWidthF(line_width)
        pen.setColor(color)
        self.line.setPen(pen)
        self.point.setPen(pen)

    def x(self):
        return self._x1

    def y(self):
        return self._y1

    def angle(self):
        return self._angle

    @pyqtProperty(QVector3D)
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, value):
        self._pos = value
        self._x1 = self._pos.x()
        self._y1 = self._pos.y()
        self._angle = value.z()
        self._x2 = self._x1 + self._length * math.cos(self._angle)
        self._y2 = self._y1 + self._length * math.sin(self._angle)
        self.line.setLine(self._x1, self._y1, self._x2, self._y2)
        self.rect = QRectF(self._x1 - self._point_radius,
                           self._y1 - self._point_radius,
                           2 * self._point_radius, 2 * self._point_radius)
        self.point.setRect(self.rect)
    def make_cursor(self):
        pen = QPen(QColor(0, 255, 0))
        h_line = QGraphicsLineItem(-10, 0, 10, 0)
        v_line = QGraphicsLineItem(0, -10, 0, 10)

        pen.setWidth(1)
        h_line.setPen(pen)
        v_line.setPen(pen)

        self.point_cursor = QGraphicsItemGroup()
        self.point_cursor.addToGroup(h_line)
        self.point_cursor.addToGroup(v_line)
        self.point_cursor.setZValue(1)
        self.point_cursor.setVisible(False)
        self.scene().addItem(self.point_cursor)
	def __init__(self, origX, origY, perCell, n):
		super(GridItem, self).__init__();
		length = perCell*n/2;
		pen = QPen(Qt.DashLine);
		pen.setColor(QColor(230, 230, 230))
		pen.setWidth(0);
		x1, y1, x2, y2 = origX-length, origY-length, origX-length, origY+length
		for i in range(1, n):
			line = QGraphicsLineItem(x1, y1, x2, y2, self)
			line.setPen(pen)
			x1, y1, x2, y2 = x1+perCell, y1, x2+perCell, y2
		x1, y1, x2, y2 = origX-length, origY-length, origX+length, origY-length
		for i in range(1, n):
			line = QGraphicsLineItem(x1, y1, x2, y2, self)
			line.setPen(pen)
			x1, y1, x2, y2 = x1, y1+perCell, x2, y2+perCell
Beispiel #36
0
 def createArrow(self):
     rad = self._RADIUS
     pen = QPen()
     pen.setWidth(3)
     color = QColor(Qt.blue)
     color.setAlphaF(0.25)
     pen.setBrush(color)
     if self._virtual_helix.isEvenParity():
         arrow = QGraphicsLineItem(rad, rad, 2*rad, rad, self)
     else:
         arrow = QGraphicsLineItem(0, rad, rad, rad, self)
     arrow.setTransformOriginPoint(rad, rad)
     arrow.setZValue(400)
     arrow.setPen(pen)
     self.arrow = arrow
     self.arrow.hide()
    def drawNewFence(self, fps):
        self.clearFencePoints()

        prev_fp = None
        for i in range(1, len(fps)):
            if prev_fp is not None:
                prev_x = prev_fp.lon
                prev_y = -prev_fp.lat
                mapped_x = fps[i].lon
                mapped_y = -fps[i].lat

                next_line = QGraphicsLineItem(prev_x, prev_y, 
                    mapped_x, mapped_y, self.__fence_layer)
                l_pen = QPen(QColor(0, 255, 0))
                l_pen.setWidth(0.1)
                next_line.setPen(l_pen)
                self.__fence_layer.addToGroup(next_line)

            prev_fp = fps[i]
Beispiel #38
0
    def moveTo(self, pos):
        # data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x, y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(QPen(QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        # update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX, oldY), QSize(1, 1))
        # grow bounding box
        self.bb.setLeft(min(self.bb.left(), max(0, x - self.brushSize // 2 - 1)))
        self.bb.setRight(max(self.bb.right(), min(self.sliceRect[0] - 1, x + self.brushSize // 2 + 1)))
        self.bb.setTop(min(self.bb.top(), max(0, y - self.brushSize // 2 - 1)))
        self.bb.setBottom(max(self.bb.bottom(), min(self.sliceRect[1] - 1, y + self.brushSize // 2 + 1)))

        # update/move position
        self.pos = pos
Beispiel #39
0
    def drawGrid(self):
        black_notes = [2,4,6,9,11]
        scale_bar = QGraphicsRectItem(0, 0, self.grid_width, self.note_height, self.piano)
        scale_bar.setPos(self.piano_width, 0)
        scale_bar.setBrush(QColor(100,100,100))
        clearpen = QPen(QColor(0,0,0,0))
        for i in range(self.end_octave - self.start_octave, self.start_octave - self.start_octave, -1):
            for j in range(self.notes_in_octave, 0, -1):
                scale_bar = QGraphicsRectItem(0, 0, self.grid_width, self.note_height, self.piano)
                scale_bar.setPos(self.piano_width, self.note_height * j + self.octave_height * (i - 1))
                scale_bar.setPen(clearpen)
                if j not in black_notes:
                    scale_bar.setBrush(QColor(120,120,120))
                else:
                    scale_bar.setBrush(QColor(100,100,100))

        measure_pen = QPen(QColor(0, 0, 0, 120), 3)
        half_measure_pen = QPen(QColor(0, 0, 0, 40), 2)
        line_pen = QPen(QColor(0, 0, 0, 40))
        for i in range(0, int(self.num_measures) + 1):
            measure = QGraphicsLineItem(0, 0, 0, self.piano_height + self.header_height - measure_pen.width(), self.header)
            measure.setPos(self.measure_width * i, 0.5 * measure_pen.width())
            measure.setPen(measure_pen)
            if i < self.num_measures:
                number = QGraphicsSimpleTextItem('%d' % (i + 1), self.header)
                number.setPos(self.measure_width * i + 5, 2)
                number.setBrush(Qt.white)
                for j in self.frange(0, self.time_sig[0]*self.grid_div/self.time_sig[1], 1.):
                    line = QGraphicsLineItem(0, 0, 0, self.piano_height, self.header)
                    line.setZValue(1.0)
                    line.setPos(self.measure_width * i + self.value_width * j, self.header_height)
                    if j == self.time_sig[0]*self.grid_div/self.time_sig[1] / 2.0:
                        line.setPen(half_measure_pen)
                    else:
                        line.setPen(line_pen)
Beispiel #40
0
    def onMouseMove_draw(self, imageview, event):
        self._navIntr.onMouseMove_default(imageview, event)

        o = imageview.scene().data2scene.map(QPointF(imageview.oldX, imageview.oldY))
        n = imageview.scene().data2scene.map(QPointF(imageview.x, imageview.y))

        # Draw temporary line for the brush stroke so the user gets feedback before the data is really updated.
        pen = QPen(
            QBrush(self._brushingCtrl._brushingModel.drawColor),
            self._brushingCtrl._brushingModel.brushSize,
            Qt.SolidLine,
            Qt.RoundCap,
            Qt.RoundJoin,
        )
        line = QGraphicsLineItem(o.x(), o.y(), n.x(), n.y())
        line.setPen(pen)

        imageview.scene().addItem(line)
        line.setParentItem(imageview.scene().dataRectItem)

        self._lineItems.append(line)
        self._brushingCtrl._brushingModel.moveTo(imageview.mousePos)
    def drawWPLine(self, wp1, wp2):
        if wp1 is None or wp2 is None:
            print("Error: Can't draw line for Null endpoint")
            return
    
        rad = self.__wp_diameter * 0.5
        mapped_wp1_x = wp1.y - rad
        mapped_wp1_y = -wp1.x
        #tangential approach?
        if (wp1.command == mavutil.mavlink.MAV_CMD_NAV_LOITER_TO_ALT
                and wp1.param1 == 1.0):
            l_rad = abs(self.__wp_loiter_radius)
            if l_rad is not None:
                dis = acs_math.gps_distance(wp1.x, wp1.y, wp2.x, wp2.y)
                theta = math.degrees(math.atan(l_rad / dis))

                #sign of self.__wp_loiter_radius indicates the direction of the
                #loiter (negative is counter-clockwise, postive is clockwise)
                #Also, the waypoint itself can override the default setting
                #via param2
                if ((wp1.param2 == 0 and self.__wp_loiter_radius > 0.0) or
                     wp1.param2 > 0.0):
                    theta = -theta

                tan_dis = math.sqrt( dis * dis - l_rad * l_rad)
                bearing = acs_math.gps_bearing(wp2.x, wp2.y, wp1.x, wp1.y)

                (tan_wp_x, tan_wp_y) = acs_math.gps_newpos(wp2.x, wp2.y,
                    bearing - theta, tan_dis)

                mapped_wp1_x = tan_wp_y - rad
                mapped_wp1_y = -tan_wp_x

        next_line = QGraphicsLineItem(mapped_wp1_x, mapped_wp1_y,
                            wp2.y - rad, -wp2.x, self.__mission_layer)
        l_pen = QPen(QColor(255, 255, 255))
        l_pen.setWidth(0.00002)
        next_line.setPen(l_pen)
        self.__mission_layer.addToGroup(next_line)
 def create_axis(self):
     counter = 0
     while self.surface[0][counter] is None: #get the first tile
         counter += 1
     # determining the distance from left side
     left_coordinate = abs(self.surface[0][counter].point.X())
     distance = (left_coordinate + counter * self.sampling_distance) * self.height_multiplier
     pen = QPen()
     pen.setWidthF(0.5)
     self.graph_zero[0] = self.position[0] + self.margin - self.line_extend
     self.graph_zero[1] = self.position[1] + distance + self.margin
     self.graph_end[0] = self.graph_zero[0] + self.content_width + self.line_extend
     self.graph_end[1] = self.graph_zero[1]
     line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], self.graph_zero[1], self.graph_end[0], self.graph_end[1])
     line_item_horizontal.setPen(pen)
     self.addToGroup(line_item_horizontal)
     center = (self.graph_zero[0] + self.line_extend), self.graph_zero[1]
     y_top = center[1] - distance
     y_bottom = self.position[1] + self.margin + len(self.surface[0]) * self.sampling_distance * self.height_multiplier
     line_item_vertical = QGraphicsLineItem(center[0], y_top, center[0], y_bottom)
     line_item_vertical.setPen(pen)
     self.addToGroup(line_item_vertical)
Beispiel #43
0
 def createArrows(self):
     rad = _RADIUS
     pen1 = self._pen1
     pen2 = self._pen2
     pen1.setWidth(3)
     pen2.setWidth(3)
     pen1.setBrush(Qt.gray)
     pen2.setBrush(Qt.lightGray)
     if self._virtual_helix.isEvenParity():
         arrow1 = QGraphicsLineItem(rad, rad, 2*rad, rad, self)
         arrow2 = QGraphicsLineItem(0, rad, rad, rad, self)
     else:
         arrow1 = QGraphicsLineItem(0, rad, rad, rad, self)
         arrow2 = QGraphicsLineItem(rad, rad, 2*rad, rad, self)
     arrow1.setTransformOriginPoint(rad, rad)
     arrow2.setTransformOriginPoint(rad, rad)
     arrow1.setZValue(400)
     arrow2.setZValue(400)
     arrow1.setPen(pen1)
     arrow2.setPen(pen2)
     self.arrow1 = arrow1
     self.arrow2 = arrow2
     self.arrow1.hide()
     self.arrow2.hide()
Beispiel #44
0
class ParticipantItem(QGraphicsItem):
    def __init__(self, model_item: Participant, parent=None):
        super().__init__(parent)

        self.model_item = model_item

        self.text = QGraphicsTextItem(self)

        self.line = QGraphicsLineItem(self)
        self.line.setPen(QPen(Qt.darkGray, 1, Qt.DashLine, Qt.RoundCap, Qt.RoundJoin))

        self.refresh()

    def update_position(self, x_pos=-1, y_pos=-1):
        if x_pos == -1:
            x_pos = self.x_pos()

        if y_pos == -1:
            y_pos = self.line.line().y2()

        self.text.setPos(x_pos - (self.text.boundingRect().width() / 2), 0)
        self.line.setLine(x_pos, 30, x_pos, y_pos)

    def x_pos(self):
        return self.line.line().x1()

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

    def refresh(self):
        self.text.setPlainText("?" if not self.model_item else self.model_item.shortname)
        if hasattr(self.model_item, "simulate") and self.model_item.simulate:
            font = QFont()
            font.setBold(True)
            self.text.setFont(font)
            self.text.setDefaultTextColor(Qt.darkGreen)
            self.line.setPen(QPen(Qt.darkGreen, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        else:
            self.text.setFont(QFont())
            self.text.setDefaultTextColor(constants.LINECOLOR)
            self.line.setPen(QPen(Qt.darkGray, 1, Qt.DashLine, Qt.RoundCap, Qt.RoundJoin))

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

    def paint(self, painter, option, widget):
        pass
Beispiel #45
0
class AnalogClock(Desklet):

    def __init__(self):
        super().__init__()

        self.center_x = 0
        self.center_y = 0
        self.radius = 1

        self.now = datetime.utcfromtimestamp(0)

        # build the clock face
        self.circle = QGraphicsEllipseItem(self.root)

        self.lines = []
        for _ in range(0, 60):
            self.lines.append(QGraphicsLineItem(self.root))

        self.hours_hand = QGraphicsLineItem(self.root)
        self.minutes_hand = QGraphicsLineItem(self.root)
        self.seconds_hand = QGraphicsLineItem(self.root)

        self.hand_circle = QGraphicsEllipseItem(self.root)

    def set_style(self, style):
        super().set_style(style)

        # minute
        pen = QPen(self.style.foreground_color)
        pen.setWidth(12)
        pen.setCapStyle(Qt.RoundCap)
        self.minutes_hand.setPen(pen)

        # hour
        pen = QPen(self.style.foreground_color)
        pen.setWidth(16)
        pen.setCapStyle(Qt.RoundCap)
        self.hours_hand.setPen(pen)

        # second
        pen = QPen(self.style.midcolor)
        pen.setWidth(4)
        pen.setCapStyle(Qt.RoundCap)
        self.seconds_hand.setPen(pen)

        # outer circle
        pen = QPen(self.style.foreground_color)
        pen.setWidth(6)
        self.circle.setPen(pen)

        # inner circle
        self.hand_circle.setBrush(QBrush(self.style.background_color))

        # minute lines
        pen = QPen()
        pen.setCapStyle(Qt.RoundCap)
        pen.setColor(self.style.midcolor)
        pen.setWidth(4)

        bold_pen = QPen()
        bold_pen.setCapStyle(Qt.RoundCap)
        bold_pen.setColor(self.style.foreground_color)
        bold_pen.setWidth(6)

        for i, line in enumerate(self.lines):
            if i % 5 == 0:
                line.setPen(bold_pen)
            else:
                line.setPen(pen)

        self.layout()

    def set_rect(self, rect):
        super().set_rect(rect)
        self.layout()

    def layout(self):
        self.center_x = self.rect.left() + self.rect.width() / 2.0
        self.center_y = self.rect.top() + self.rect.height() / 2.0
        self.radius = min(self.rect.width(), self.rect.height()) / 2.0 - 3.0

        self.circle.setRect(self.center_x - self.radius,
                            self.center_y - self.radius,
                            2 * self.radius,
                            2 * self.radius)
        self.hand_circle.setRect(self.center_x - 5,
                                 self.center_y - 5,
                                 10, 10)

        for i, line in enumerate(self.lines):
            angle = i * 2.0 * math.pi / 60.0
            if i % 5 == 0:
                line.setLine(self.center_x + math.cos(angle) * self.radius * 0.85,
                             self.center_y + math.sin(angle) * self.radius * 0.85,
                             self.center_x + math.cos(angle) * self.radius * 0.95,
                             self.center_y + math.sin(angle) * self.radius * 0.95)
            else:
                line.setLine(self.center_x + math.cos(angle) * self.radius * 0.90,
                             self.center_y + math.sin(angle) * self.radius * 0.90,
                             self.center_x + math.cos(angle) * self.radius * 0.95,
                             self.center_y + math.sin(angle) * self.radius * 0.95)

        self.update(self.now)

    def update(self, now):
        self.now = now

        hour = (self.now.hour / 12.0 + self.now.minute / 60.0 / 12.0) * 2.0 * math.pi - math.pi / 2.0
        minute = (self.now.minute / 60.0 + self.now.second / 60.0 / 60.0) * 2.0 * math.pi - math.pi / 2.0
        second = (self.now.second / 60.0) * 2.0 * math.pi - math.pi / 2.0

        self.set_seconds(second)
        self.set_minutes(minute)
        self.set_hours(hour)

    def set_seconds(self, n):
        self.seconds_hand.setLine(
            self.center_x + math.cos(n) * self.radius * 0.0,
            self.center_y + math.sin(n) * self.radius * 0.0,
            self.center_x + math.cos(n) * self.radius * 0.8,
            self.center_y + math.sin(n) * self.radius * 0.8)

    def set_minutes(self, n):
        self.minutes_hand.setLine(
            self.center_x + math.cos(n) * self.radius * 0.0,
            self.center_y + math.sin(n) * self.radius * 0.0,
            self.center_x + math.cos(n) * self.radius * 0.8,
            self.center_y + math.sin(n) * self.radius * 0.8)

    def set_hours(self, n):
        self.hours_hand.setLine(
            self.center_x + math.cos(n) * self.radius * 0.0,
            self.center_y + math.sin(n) * self.radius * 0.0,
            self.center_x + math.cos(n) * self.radius * 0.45,
            self.center_y + math.sin(n) * self.radius * 0.45)
class BaseGraphic(object):
    def __init__(self, *args):
        super(BaseGraphic, self).__init__()
        self.label = args[3]
        self.parent = args[0]
        self.section_analyzer = self.parent.section_analyzer
        self.width = None
        self.height = None
        self.margin = None
        self.position = args[1], args[2]
        self.content_width = None
        self.content_height = None
        self.distance_pointer = None
        self.distance_label = None
        self.section_num = len(self.section_analyzer.section_list)
        self.section_distance = self.section_analyzer.section_distance
        self.length_multiplier = 100.0
        self.height_multiplier = 100.0
        self.line_extend = 20
        self.margin = 50
        self.material_legend = MaterialLegend(self)
        self._inited = False
        self.items = []
        self.add_title()

    def add_title(self):
        if self.label:
            title = QGraphicsSimpleTextItem(self.label)
            title.setPos(self.position[0] + self.margin, self.position[1] + self.line_extend)
            self.addToGroup(title)

    def addToGroup(self, item):
        self.items.append(item)

    def create_distance_pointer(self):
        self.distance_pointer = QGraphicsLineItem()
        pen = QPen()
        pen.setWidthF(1.0)
        pen.setStyle(Qt.DashDotLine)
        color = Color.create_qcolor_from_rgb_tuple_f((1,0,0))
        pen.setColor(color)
        self.distance_pointer.setPen(pen)
        self.distance_pointer.setZValue(1.0)
        self.addToGroup(self.distance_pointer)
        self.distance_label = QGraphicsSimpleTextItem()
        self.distance_label.setZValue(1.0)
        self.addToGroup(self.distance_label)


    def init_dimension(self):
        section_num = len(self.section_analyzer.section_list)
        section_distance = self.section_analyzer.section_distance
        self.content_width = section_num * section_distance * self.length_multiplier
        self.create_distance_pointer()
        self._inited = True

    def update_graph_size(self):
        if self.content_height and self.content_width:
            self.width = self.content_width + self.margin * 2
            self.height = self.content_height + self.margin * 2
        # bounding_rect.setWidth(self.width)
        # bounding_rect.setHeight(self.height)

    def set_distance_pointer(self, distance):
        if self._inited:
            x1 = self.position[0] + self.margin + distance * self.length_multiplier
            y1 = self.position[1]
            x2 = x1
            y2 = y1 + self.height
            self.distance_pointer.setLine(x1, y1, x2, y2)
            self.distance_label.setText("%.2f" % distance)
            self.distance_label.setPos(x2,y2)
        pass

    @staticmethod
    def set_rect_fill(*args):
        if args[0] == 0: #surface color mode
            rect = args[1]
            color = args[2]
            qcolor = Color.create_qcolor_from_rgb_tuple_f(color)
            brush = QBrush(qcolor)
            rect.setBrush(brush)

    def create_legend(self):
        x = self.position[0] + self.width
        y = self.position[1]
        self.material_legend.create_material_legend(x, y)
        for item in self.material_legend.graphic_items:
            self.addToGroup(item)
 def add_dummy_line(self):
     pen = QPen()
     pen.setStyle(Qt.NoPen)
     dummy_line = QGraphicsLineItem(0, 0, 0, 100)
     dummy_line.setPen(pen)
     self.scene.addItem(dummy_line)
Beispiel #48
0
class CalendarDesklet(Desklet):

    def __init__(self):
        super().__init__()

        self.model = CalendarModel()

        self.cursor_pos = None

        self.cursor = QGraphicsRectItem(self.root)
        self.header = QGraphicsSimpleTextItem(self.root)

        self.weekdays = []
        days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        for day in days:
            self.weekdays.append(QGraphicsSimpleTextItem(day, self.root))

        self.header_line = QGraphicsLineItem(self.root)

        self.days = []
        for _ in range(0, 6 * 7):
            self.days.append(QGraphicsSimpleTextItem(self.root))

    def next_month(self):
        self.model.next_month()
        self.layout()

    def previous_month(self):
        self.model.previous_month()
        self.layout()

    def set_rect(self, rect):
        super().set_rect(rect)
        self.layout()

    def set_style(self, style):
        super().set_style(style)

        font = QFont(style.font)
        font.setPixelSize(48)
        self.header.setBrush(style.midcolor)
        self.header.setFont(font)

        font = QFont(style.font)
        font.setPixelSize(32)

        self.header_line.setPen(style.foreground_color)

        self.cursor.setBrush(style.midcolor)
        self.cursor.setPen(QPen(Qt.NoPen))

        for widget in self.weekdays:
            widget.setFont(font)
            widget.setBrush(style.foreground_color)

        for widget in self.days:
            widget.setFont(font)
            widget.setBrush(self.style.foreground_color)

        self.layout()

    def layout(self):
        cell_width = (self.rect.width()) / 7.0
        cell_height = (self.rect.height() - 64) / 7.0

        x = self.rect.left()
        y = self.rect.top()

        fm = QFontMetrics(self.header.font())
        rect = fm.boundingRect(self.header.text())
        self.header.setPos(x + self.rect.width() / 2 - rect.width() / 2,
                           y)

        y += fm.height()

        for row, day in enumerate(self.weekdays):
            fm = QFontMetrics(day.font())
            rect = fm.boundingRect(day.text())
            day.setPos(x + row * cell_width + cell_width / 2 - rect.width() / 2,
                       y)

        y += fm.height()
        self.header_line.setLine(x, y,
                                 x + self.rect.width() - 3, y)

        y += 8

        for n, widget in enumerate(self.days):
            col = n % 7
            row = n // 7

            rect = fm.boundingRect(widget.text())
            widget.setPos(x + col * cell_width + cell_width / 2 - rect.width() / 2,
                          y + row * cell_height + cell_height / 2 - fm.height() / 2)

            # if day.month != self.now.month:
            #    widget.setBrush(self.style.midcolor)
            # else:

        if self.cursor_pos is not None:
            self.cursor.setRect(x + self.cursor_pos[0] * cell_width,
                                y + self.cursor_pos[1] * cell_height,
                                cell_width,
                                cell_height)
            self.cursor.show()
        else:
            self.cursor.hide()

    def update(self, now):
        self.model.update(now)

        # update header
        self.header.setText(
            date(self.model.year, self.model.month, 1).strftime("%B %Y"))

        # calculate the date of the top/left calendar entry
        current_date = date(self.model.year, self.model.month, 1)
        current_date = current_date - timedelta(current_date.weekday())

        self.cursor_pos = None
        for n, widget in enumerate(self.days):
            col = n % 7
            row = n // 7

            if current_date == self.model.today:
                self.cursor_pos = (col, row)

            widget.setText("%d" % current_date.day)
            self.days[n] = widget
            current_date += timedelta(days=1)

        self.layout()
Beispiel #49
0
class PianoRoll(QGraphicsScene):
    '''the piano roll'''

    midievent = pyqtSignal(list)
    measureupdate = pyqtSignal(int)
    modeupdate = pyqtSignal(str)

    def __init__(self, time_sig = '4/4', num_measures = 4, quantize_val = '1/8'):
        QGraphicsScene.__init__(self)
        self.setBackgroundBrush(QColor(50, 50, 50))
        self.mousePos = QPointF()

        self.notes = []
        self.selected_notes = []
        self.piano_keys = []

        self.marquee_select = False
        self.insert_mode = False
        self.velocity_mode = False
        self.place_ghost = False
        self.ghost_note = None
        self.default_ghost_vel = 100
        self.ghost_vel = self.default_ghost_vel

        ## dimensions
        self.padding = 2

        ## piano dimensions
        self.note_height = 10
        self.start_octave = -2
        self.end_octave = 8
        self.notes_in_octave = 12
        self.total_notes = (self.end_octave - self.start_octave) \
                * self.notes_in_octave + 1
        self.piano_height = self.note_height * self.total_notes
        self.octave_height = self.notes_in_octave * self.note_height

        self.piano_width = 34

        ## height
        self.header_height = 20
        self.total_height = self.piano_height - self.note_height + self.header_height
        #not sure why note_height is subtracted

        ## width
        self.full_note_width = 250 # i.e. a 4/4 note
        self.snap_value = None
        self.quantize_val = quantize_val

        ### dummy vars that will be changed
        self.time_sig = 0
        self.measure_width = 0
        self.num_measures = 0
        self.max_note_length = 0
        self.grid_width = 0
        self.value_width = 0
        self.grid_div = 0
        self.piano = None
        self.header = None
        self.play_head = None

        self.setTimeSig(time_sig)
        self.setMeasures(num_measures)
        self.setGridDiv()
        self.default_length = 1. / self.grid_div


    # -------------------------------------------------------------------------
    # Callbacks

    def movePlayHead(self, transport_info):
        # TODO: need conversion between frames and PPQ
        x = 105. # works for 120bpm
        total_duration = self.time_sig[0] * self.num_measures * x
        pos = transport_info['frame'] / x
        frac = (pos % total_duration) / total_duration
        self.play_head.setPos(QPointF(frac * self.grid_width, 0))

    def setTimeSig(self, time_sig):
        try:
           new_time_sig = list(map(float, time_sig.split('/')))
           if len(new_time_sig)==2:
               self.time_sig = new_time_sig

               self.measure_width = self.full_note_width * self.time_sig[0]/self.time_sig[1]
               self.max_note_length = self.num_measures * self.time_sig[0]/self.time_sig[1]
               self.grid_width = self.measure_width * self.num_measures
               self.setGridDiv()
        except ValueError:
            pass

    def setMeasures(self, measures):
        try:
            self.num_measures = float(measures)
            self.max_note_length = self.num_measures * self.time_sig[0]/self.time_sig[1]
            self.grid_width = self.measure_width * self.num_measures
            self.refreshScene()
        except:
            pass

    def setDefaultLength(self, length):
        try:
            v = list(map(float, length.split('/')))
            if len(v) < 3:
                self.default_length = \
                        v[0] if len(v)==1 else \
                        v[0] / v[1]
                pos = self.enforce_bounds(self.mousePos)
                if self.insert_mode: self.makeGhostNote(pos.x(), pos.y())
        except ValueError:
            pass

    def setGridDiv(self, div=None):
        if not div: div = self.quantize_val
        try:
            val = list(map(int, div.split('/')))
            if len(val) < 3:
                self.quantize_val = div
                self.grid_div = val[0] if len(val)==1 else val[1]
                self.value_width = self.full_note_width / float(self.grid_div) if self.grid_div else None
                self.setQuantize(div)

                self.refreshScene()
        except ValueError:
            pass

    def setQuantize(self, value):
        try:
            val = list(map(float, value.split('/')))
            if len(val) == 1:
                self.quantize(val[0])
                self.quantize_val = value
            elif len(val) == 2:
                self.quantize(val[0] / val[1])
                self.quantize_val = value
        except ValueError:
            pass

    # -------------------------------------------------------------------------
    # Event Callbacks

    def keyPressEvent(self, event):
        QGraphicsScene.keyPressEvent(self, event)
        if event.key() == Qt.Key_F:
            if not self.insert_mode:
                self.velocity_mode = False
                self.insert_mode = True
                self.makeGhostNote(self.mousePos.x(), self.mousePos.y())
                self.modeupdate.emit('insert_mode')
            elif self.insert_mode:
                self.insert_mode = False
                if self.place_ghost: self.place_ghost = False
                self.removeItem(self.ghost_note)
                self.ghost_note = None
                self.modeupdate.emit('')
        elif event.key() == Qt.Key_D:
            if self.velocity_mode:
                self.velocity_mode = False
                self.modeupdate.emit('')
            else:
                if self.insert_mode:
                    self.removeItem(self.ghost_note)
                self.ghost_note = None
                self.insert_mode = False
                self.place_ghost = False
                self.velocity_mode = True
                self.modeupdate.emit('velocity_mode')
        elif event.key() == Qt.Key_A:
            if all((note.isSelected() for note in self.notes)):
                for note in self.notes:
                    note.setSelected(False)
                self.selected_notes = []
            else:
                for note in self.notes:
                    note.setSelected(True)
                self.selected_notes = self.notes[:]
        elif event.key() in (Qt.Key_Delete, Qt.Key_Backspace):
            self.notes = [note for note in self.notes if note not in self.selected_notes]
            for note in self.selected_notes:
                self.removeItem(note)
                self.midievent.emit(["midievent-remove", note.note[0], note.note[1], note.note[2], note.note[3]])
                del note
            self.selected_notes = []

    def mousePressEvent(self, event):
        QGraphicsScene.mousePressEvent(self, event)
        if not (any(key.pressed for key in self.piano_keys)
                or any(note.pressed for note in self.notes)):
            for note in self.selected_notes:
                note.setSelected(False)
            self.selected_notes = []

            if event.button() == Qt.LeftButton:
                if self.insert_mode:
                    self.place_ghost = True
                else:
                    self.marquee_select = True
                    self.marquee_rect = QRectF(event.scenePos().x(), event.scenePos().y(), 1, 1)
                    self.marquee = QGraphicsRectItem(self.marquee_rect)
                    self.marquee.setBrush(QColor(255, 255, 255, 100))
                    self.addItem(self.marquee)
        else:
            for s_note in self.notes:
                if s_note.pressed and s_note in self.selected_notes:
                    break
                elif s_note.pressed and s_note not in self.selected_notes:
                    for note in self.selected_notes:
                        note.setSelected(False)
                    self.selected_notes = [s_note]
                    break
            for note in self.selected_notes:
                if not self.velocity_mode:
                    note.mousePressEvent(event)

    def mouseMoveEvent(self, event):
        QGraphicsScene.mouseMoveEvent(self, event)
        self.mousePos = event.scenePos()
        if not (any((key.pressed for key in self.piano_keys))):
            m_pos = event.scenePos()
            if self.insert_mode and self.place_ghost: #placing a note
                m_width = self.ghost_rect.x() + self.ghost_rect_orig_width
                if m_pos.x() > m_width:
                    m_new_x = self.snap(m_pos.x())
                    self.ghost_rect.setRight(m_new_x)
                    self.ghost_note.setRect(self.ghost_rect)
                #self.adjust_note_vel(event)
            else:
                m_pos = self.enforce_bounds(m_pos)

                if self.insert_mode: #ghostnote follows mouse around
                    (m_new_x, m_new_y) = self.snap(m_pos.x(), m_pos.y())
                    self.ghost_rect.moveTo(m_new_x, m_new_y)
                    try:
                        self.ghost_note.setRect(self.ghost_rect)
                    except RuntimeError:
                        self.ghost_note = None
                        self.makeGhostNote(m_new_x, m_new_y)

                elif self.marquee_select:
                    marquee_orig_pos = event.buttonDownScenePos(Qt.LeftButton)
                    if marquee_orig_pos.x() < m_pos.x() and marquee_orig_pos.y() < m_pos.y():
                        self.marquee_rect.setBottomRight(m_pos)
                    elif marquee_orig_pos.x() < m_pos.x() and marquee_orig_pos.y() > m_pos.y():
                        self.marquee_rect.setTopRight(m_pos)
                    elif marquee_orig_pos.x() > m_pos.x() and marquee_orig_pos.y() < m_pos.y():
                        self.marquee_rect.setBottomLeft(m_pos)
                    elif marquee_orig_pos.x() > m_pos.x() and marquee_orig_pos.y() > m_pos.y():
                        self.marquee_rect.setTopLeft(m_pos)
                    self.marquee.setRect(self.marquee_rect)
                    self.selected_notes = []
                    for item in self.collidingItems(self.marquee):
                        if item in self.notes:
                            self.selected_notes.append(item)

                    for note in self.notes:
                        if note in self.selected_notes: note.setSelected(True)
                        else: note.setSelected(False)

                elif self.velocity_mode:
                    if Qt.LeftButton == event.buttons():
                        for note in self.selected_notes:
                            note.updateVelocity(event)

                elif not self.marquee_select: #move selected
                    if Qt.LeftButton == event.buttons():
                        x = y = False
                        if any(note.back.stretch for note in self.selected_notes):
                            x = True
                        elif any(note.front.stretch for note in self.selected_notes):
                            y = True
                        for note in self.selected_notes:
                            note.back.stretch = x
                            note.front.stretch = y
                            note.moveEvent(event)

    def mouseReleaseEvent(self, event):
        if not (any((key.pressed for key in self.piano_keys)) or any((note.pressed for note in self.notes))):
            if event.button() == Qt.LeftButton:
                if self.place_ghost and self.insert_mode:
                    self.place_ghost = False
                    note_start = self.get_note_start_from_x(self.ghost_rect.x())
                    note_num = self.get_note_num_from_y(self.ghost_rect.y())
                    note_length = self.get_note_length_from_x(self.ghost_rect.width())
                    self.drawNote(note_num, note_start, note_length, self.ghost_vel)
                    self.midievent.emit(["midievent-add", note_num, note_start, note_length, self.ghost_vel])
                    self.makeGhostNote(self.mousePos.x(), self.mousePos.y())
                elif self.marquee_select:
                    self.marquee_select = False
                    self.removeItem(self.marquee)
        elif not self.marquee_select:
            for note in self.selected_notes:
                old_info = note.note[:]
                note.mouseReleaseEvent(event)
                if self.velocity_mode:
                    note.setSelected(True)
                if not old_info == note.note:
                    self.midievent.emit(["midievent-remove", old_info[0], old_info[1], old_info[2], old_info[3]])
                    self.midievent.emit(["midievent-add", note.note[0], note.note[1], note.note[2], note.note[3]])

    # -------------------------------------------------------------------------
    # Internal Functions

    def drawHeader(self):
        self.header = QGraphicsRectItem(0, 0, self.grid_width, self.header_height)
        #self.header.setZValue(1.0)
        self.header.setPos(self.piano_width, 0)
        self.addItem(self.header)

    def drawPiano(self):
        piano_keys_width = self.piano_width - self.padding
        labels = ('B','Bb','A','Ab','G','Gb','F','E','Eb','D','Db','C')
        black_notes = (2,4,6,9,11)
        piano_label = QFont()
        piano_label.setPointSize(6)
        self.piano = QGraphicsRectItem(0, 0, piano_keys_width, self.piano_height)
        self.piano.setPos(0, self.header_height)
        self.addItem(self.piano)

        key = PianoKeyItem(piano_keys_width, self.note_height, self.piano)
        label = QGraphicsSimpleTextItem('C8', key)
        label.setPos(18, 1)
        label.setFont(piano_label)
        key.setBrush(QColor(255, 255, 255))
        for i in range(self.end_octave - self.start_octave, self.start_octave - self.start_octave, -1):
            for j in range(self.notes_in_octave, 0, -1):
                if j in black_notes:
                    key = PianoKeyItem(piano_keys_width/1.4, self.note_height, self.piano)
                    key.setBrush(QColor(0, 0, 0))
                    key.setZValue(1.0)
                    key.setPos(0, self.note_height * j + self.octave_height * (i - 1))
                elif (j - 1) and (j + 1) in black_notes:
                    key = PianoKeyItem(piano_keys_width, self.note_height * 2, self.piano)
                    key.setBrush(QColor(255, 255, 255))
                    key.setPos(0, self.note_height * j + self.octave_height * (i - 1) - self.note_height/2.)
                elif (j - 1) in black_notes:
                    key = PianoKeyItem(piano_keys_width, self.note_height * 3./2, self.piano)
                    key.setBrush(QColor(255, 255, 255))
                    key.setPos(0, self.note_height * j + self.octave_height * (i - 1) - self.note_height/2.)
                elif (j + 1) in black_notes:
                    key = PianoKeyItem(piano_keys_width, self.note_height * 3./2, self.piano)
                    key.setBrush(QColor(255, 255, 255))
                    key.setPos(0, self.note_height * j + self.octave_height * (i - 1))
                if j == 12:
                    label = QGraphicsSimpleTextItem('{}{}'.format(labels[j - 1], self.end_octave - i), key )
                    label.setPos(18, 6)
                    label.setFont(piano_label)
                self.piano_keys.append(key)

    def drawGrid(self):
        black_notes = [2,4,6,9,11]
        scale_bar = QGraphicsRectItem(0, 0, self.grid_width, self.note_height, self.piano)
        scale_bar.setPos(self.piano_width, 0)
        scale_bar.setBrush(QColor(100,100,100))
        clearpen = QPen(QColor(0,0,0,0))
        for i in range(self.end_octave - self.start_octave, self.start_octave - self.start_octave, -1):
            for j in range(self.notes_in_octave, 0, -1):
                scale_bar = QGraphicsRectItem(0, 0, self.grid_width, self.note_height, self.piano)
                scale_bar.setPos(self.piano_width, self.note_height * j + self.octave_height * (i - 1))
                scale_bar.setPen(clearpen)
                if j not in black_notes:
                    scale_bar.setBrush(QColor(120,120,120))
                else:
                    scale_bar.setBrush(QColor(100,100,100))

        measure_pen = QPen(QColor(0, 0, 0, 120), 3)
        half_measure_pen = QPen(QColor(0, 0, 0, 40), 2)
        line_pen = QPen(QColor(0, 0, 0, 40))
        for i in range(0, int(self.num_measures) + 1):
            measure = QGraphicsLineItem(0, 0, 0, self.piano_height + self.header_height - measure_pen.width(), self.header)
            measure.setPos(self.measure_width * i, 0.5 * measure_pen.width())
            measure.setPen(measure_pen)
            if i < self.num_measures:
                number = QGraphicsSimpleTextItem('%d' % (i + 1), self.header)
                number.setPos(self.measure_width * i + 5, 2)
                number.setBrush(Qt.white)
                for j in self.frange(0, self.time_sig[0]*self.grid_div/self.time_sig[1], 1.):
                    line = QGraphicsLineItem(0, 0, 0, self.piano_height, self.header)
                    line.setZValue(1.0)
                    line.setPos(self.measure_width * i + self.value_width * j, self.header_height)
                    if j == self.time_sig[0]*self.grid_div/self.time_sig[1] / 2.0:
                        line.setPen(half_measure_pen)
                    else:
                        line.setPen(line_pen)

    def drawPlayHead(self):
        self.play_head = QGraphicsLineItem(self.piano_width, self.header_height, self.piano_width, self.total_height)
        self.play_head.setPen(QPen(QColor(255,255,255,50), 2))
        self.play_head.setZValue(1.)
        self.addItem(self.play_head)

    def refreshScene(self):
        list(map(self.removeItem, self.notes))
        self.selected_notes = []
        self.piano_keys = []
        self.clear()
        self.drawPiano()
        self.drawHeader()
        self.drawGrid()
        self.drawPlayHead()
        for note in self.notes[:]:
            if note.note[1] >= (self.num_measures * self.time_sig[0]):
                self.notes.remove(note)
                self.midievent.emit(["midievent-remove", note.note[0], note.note[1], note.note[2], note.note[3]])
            elif note.note[2] > self.max_note_length:
                new_note = note.note[:]
                new_note[2] = self.max_note_length
                self.notes.remove(note)
                self.drawNote(new_note[0], new_note[1], self.max_note_length, new_note[3], False)
                self.midievent.emit(["midievent-remove", note.note[0], note.note[1], note.note[2], note.note[3]])
                self.midievent.emit(["midievent-add", new_note[0], new_note[1], new_note[2], new_note[3]])
        list(map(self.addItem, self.notes))
        if self.views():
            self.views()[0].setSceneRect(self.itemsBoundingRect())

    def clearNotes(self):
        self.clear()
        self.notes = []
        self.selected_notes = []
        self.drawPiano()
        self.drawHeader()
        self.drawGrid()

    def makeGhostNote(self, pos_x, pos_y):
        """creates the ghostnote that is placed on the scene before the real one is."""
        if self.ghost_note:
            self.removeItem(self.ghost_note)
        length = self.full_note_width * self.default_length
        (start, note) = self.snap(pos_x, pos_y)
        self.ghost_vel = self.default_ghost_vel
        self.ghost_rect = QRectF(start, note, length, self.note_height)
        self.ghost_rect_orig_width = self.ghost_rect.width()
        self.ghost_note = QGraphicsRectItem(self.ghost_rect)
        self.ghost_note.setBrush(QColor(230, 221, 45, 100))
        self.addItem(self.ghost_note)

    def drawNote(self, note_num, note_start=None, note_length=None, note_velocity=None, add=True):
        """
        note_num: midi number, 0 - 127
        note_start: 0 - (num_measures * time_sig[0]) so this is in beats
        note_length: 0 - (num_measures  * time_sig[0]/time_sig[1]) this is in measures
        note_velocity: 0 - 127
        """

        info = [note_num, note_start, note_length, note_velocity]

        if not note_start % (self.num_measures * self.time_sig[0]) == note_start:
            #self.midievent.emit(["midievent-remove", note_num, note_start, note_length, note_velocity])
            while not note_start % (self.num_measures * self.time_sig[0]) == note_start:
                self.setMeasures(self.num_measures+1)
            self.measureupdate.emit(self.num_measures)
            self.refreshScene()

        x_start = self.get_note_x_start(note_start)
        if note_length > self.max_note_length:
            note_length = self.max_note_length + 0.25
        x_length = self.get_note_x_length(note_length)
        y_pos = self.get_note_y_pos(note_num)

        note = NoteItem(self.note_height, x_length, info)
        note.setPos(x_start, y_pos)

        self.notes.append(note)
        if add:
            self.addItem(note)

    # -------------------------------------------------------------------------
    # Helper Functions

    def frange(self, x, y, t):
        while x < y:
            yield x
            x += t

    def quantize(self, value):
        self.snap_value = float(self.full_note_width) * value if value else None

    def snap(self, pos_x, pos_y = None):
        if self.snap_value:
            pos_x = int(round((pos_x - self.piano_width) / self.snap_value)) \
                    * self.snap_value + self.piano_width
        if pos_y:
            pos_y = int((pos_y - self.header_height) / self.note_height) \
                    * self.note_height + self.header_height
        return (pos_x, pos_y) if pos_y else pos_x

    def adjust_note_vel(self, event):
        m_pos = event.scenePos()
        #bind velocity to vertical mouse movement
        self.ghost_vel += (event.lastScenePos().y() - m_pos.y())/10
        if self.ghost_vel < 0:
            self.ghost_vel = 0
        elif self.ghost_vel > 127:
            self.ghost_vel = 127

        m_width = self.ghost_rect.x() + self.ghost_rect_orig_width
        if m_pos.x() < m_width:
            m_pos.setX(m_width)
        m_new_x = self.snap(m_pos.x())
        self.ghost_rect.setRight(m_new_x)
        self.ghost_note.setRect(self.ghost_rect)


    def enforce_bounds(self, pos):
        if pos.x() < self.piano_width:
            pos.setX(self.piano_width)
        elif pos.x() > self.grid_width + self.piano_width:
            pos.setX(self.grid_width + self.piano_width)
        if pos.y() < self.header_height + self.padding:
            pos.setY(self.header_height + self.padding)
        return pos

    def get_note_start_from_x(self, note_x):
        return (note_x - self.piano_width) / (self.grid_width / self.num_measures / self.time_sig[0])


    def get_note_x_start(self, note_start):
        return self.piano_width + \
                (self.grid_width / self.num_measures / self.time_sig[0]) * note_start

    def get_note_x_length(self, note_length):
        return float(self.time_sig[1]) / self.time_sig[0] * note_length * self.grid_width / self.num_measures

    def get_note_length_from_x(self, note_x):
        return float(self.time_sig[0]) / self.time_sig[1] * self.num_measures / self.grid_width \
                * note_x


    def get_note_y_pos(self, note_num):
        return self.header_height + self.note_height * (self.total_notes - note_num - 1)

    def get_note_num_from_y(self, note_y_pos):
        return -(((note_y_pos - self.header_height) / self.note_height) - self.total_notes + 1)
Beispiel #50
0
class PreXoverItemGroup(QGraphicsEllipseItem):
    """Summary

    Attributes:
        active_wedge_gizmo (TYPE): Description
        fwd_prexover_items (dict): Description
        HUE_FACTOR (float): Description
        id_num (TYPE): Description
        is_active (TYPE): Description
        model_part (Part): The model part
        rev_prexover_items (dict): Description
        SPIRAL_FACTOR (float): Description
        virtual_helix_item (VirtualHelixItem): Description
    """
    HUE_FACTOR = 1.6
    SPIRAL_FACTOR = 0.4

    def __init__(self, radius, rect, virtual_helix_item, is_active):
        """Summary

        Args:
            radius (TYPE): Description
            rect (TYPE): Description
            virtual_helix_item (VirtualHelixItem): Description
            is_active (TYPE): Description
        """
        super(PreXoverItemGroup, self).__init__(rect, virtual_helix_item)

        self._radius = radius
        self._rect = rect
        self.virtual_helix_item = virtual_helix_item
        self.model_part = virtual_helix_item.part()
        self.id_num = virtual_helix_item.idNum()
        self.is_active = is_active
        self.active_wedge_gizmo = WedgeGizmo(radius, rect, self)
        self.fwd_prexover_items = fwd_pxis = {}
        self.rev_prexover_items = rev_pxis = {}
        self._colors = self._getColors()
        self.addItems()
        self.setPen(getNoPen())
        z = styles.ZPXIGROUP + 10 if is_active else styles.ZPXIGROUP
        self.setZValue(z)
        self.setTransformOriginPoint(rect.center())

        bpr, tpr, eulerZ = virtual_helix_item.getProperty(['bases_per_repeat',
                                                           'turns_per_repeat',
                                                           'eulerZ'])

        self.setRotation(-eulerZ)  # add 180

        # for baseNearestPoint
        fwd_pos, rev_pos = [], []
        step_size = self.virtual_helix_item.getProperty('bases_per_repeat')
        for i in range(int(step_size)):
            fwd_pos.append((fwd_pxis[i].scenePos().x(),
                            fwd_pxis[i].scenePos().y()))
            rev_pos.append((rev_pxis[i].scenePos().x(),
                            rev_pxis[i].scenePos().y()))
        self.fwd_pos_array = np.asarray(fwd_pos)
        self.rev_pos_array = np.asarray(rev_pos)
        self.baseNearLine = QGraphicsLineItem(self)
        self.baseNearLine.setPen(getPenObj("#000000", 0.25, capstyle=Qt.RoundCap))
    # end def

    def mousePressEvent(self, event):
        print("PreXoverGroup press")

    def mouseMoveEvent(self, event):
        print("PreXoverGroup move")

    def mouseReleaseEvent(self, event):
        print("PreXoverGroup release")

    ### ACCESSORS ###
    def partItem(self):
        """Summary

        Returns:
            TYPE: Description
        """
        return self.virtual_helix_item.partItem()
    # end def

    def getItem(self, is_fwd, step_idx):
        """Summary

        Args:
            is_fwd (TYPE): Description
            step_idx (int): the base index within the virtual helix

        Returns:
            TYPE: Description
        """
        items = self.fwd_prexover_items if is_fwd else self.rev_prexover_items
        if step_idx in items:
            return items[step_idx]
        else:
            return None
    # end def

    def getItemIdx(self, is_fwd, idx):
        """Summary

        Args:
            is_fwd (TYPE): Description
            idx (int): the base index within the virtual helix

        Returns:
            TYPE: Description
        """
        step_size = self.virtual_helix_item.getProperty('bases_per_repeat')
        return self.getItem(is_fwd, idx % step_size)
    # end def

    ### EVENT HANDLERS ###

    ### PRIVATE SUPPORT METHODS ###
    def _getColors(self):
        """Summary

        Returns:
            TYPE: Description
        """
        step_size = int(self.virtual_helix_item.getProperty('bases_per_repeat'))
        hue_scale = step_size*self.HUE_FACTOR
        return [QColor.fromHsvF(i / hue_scale, 0.75, 0.8).name() for i in range(step_size)]
    # end def

    ### PUBLIC SUPPORT METHODS ###
    def addItems(self):
        """Summary
        """
        radius = self._radius
        step_size, bases_per_turn, tpb, mgroove = self.virtual_helix_item.getAngularProperties()
        # print("TPB", tpb, step_size)
        iw = PXI_PP_ITEM_WIDTH
        spiral_factor = self.SPIRAL_FACTOR
        colors = self._colors
        ctr = self.mapToParent(self._rect).boundingRect().center()
        x = ctr.x() + radius - PXI_PP_ITEM_WIDTH
        y = ctr.y()
        # tpb = -tpb
        # Qt +angle is Clockwise (CW), model +angle is CCW
        mgroove = -mgroove
        fwd_pxis = self.fwd_prexover_items
        rev_pxis = self.rev_prexover_items
        for i in range(int(step_size)):
            inset = i*spiral_factor  # spiral layout
            fwd = PreXoverItem(i, tpb, step_size, colors[i], self, is_fwd=True)
            rev = PreXoverItem(i, tpb, step_size, colors[-1 - i], self, is_fwd=False)
            fwd.setPos(x - inset, y)
            rev.setPos(x - inset, y)
            fwd.setTransformOriginPoint((-radius + iw + inset), 0)
            rev.setTransformOriginPoint((-radius + iw + inset), 0)
            fwd.setRotation(round(i*tpb % 360, 3))
            rev.setRotation(round((i*tpb + mgroove) % 360, 3))
            fwd.setBondLineLength(inset + iw)
            rev.setBondLineLength(inset + iw)
            fwd_pxis[i] = fwd
            rev_pxis[i] = rev

        for i in range(int(step_size) - 1):
            fwd, next_fwd = fwd_pxis[i], fwd_pxis[i + 1]
            j = (step_size - 1) - i
            rev, next_rev = rev_pxis[j], rev_pxis[j - 1]
            fwd.set3pItem(next_fwd)
            rev.set3pItem(next_rev)
            next_fwd.set5pItem(fwd)
            next_rev.set5pItem(rev)
    # end def

    def baseNearestPoint(self, is_fwd, scene_pos):
        """Summary

        Args:
            is_fwd (bool): used to check fwd or rev lists.
            scene_pos (QPointF): scene coordinate position

        Returns:
            PreXoverItem: base nearest to position
        """
        pos_array = self.fwd_pos_array if is_fwd else self.rev_pos_array
        dist_2 = np.sum((pos_array - (scene_pos.x(), scene_pos.y()))**2, axis=1)
        near_idx = np.argmin(dist_2)
        near_pxi = self.fwd_prexover_items[near_idx] if is_fwd else self.rev_prexover_items[near_idx]
        # Draw a line
        p1 = self.mapFromScene(scene_pos.x(), scene_pos.y())
        p2 = self.mapFromScene(near_pxi.scenePos())
        line = QLineF(p1, p2)
        self.baseNearLine.setLine(line)

    def destroyItem(self):
        """Summary
        """
        fpxis = self.fwd_prexover_items
        rpxis = self.rev_prexover_items
        scene = self.scene()
        for i in range(len(fpxis)):
            x = fpxis.pop(i)
            x.destroyItem()
            x = rpxis.pop(i)
            x.destroyItem()
        self.virtual_helix_item = None
        self.model_part = None
        scene.removeItem(self.active_wedge_gizmo)
        self.active_wedge_gizmo = None
        scene.removeItem(self)
    # end def

    def updateTurnsPerRepeat(self):
        """Summary
        """
        step_size, bases_per_turn, tpb, mgroove = self.virtual_helix_item.getAngularProperties()
        mgroove = -mgroove
        fpxis = self.fwd_prexover_items
        rpxis = self.rev_prexover_items
        for i in range(int(step_size)):
            fwd = self.fwd_prexover_items[i]
            rev = self.rev_prexover_items[i]
            fwd.setRotation(round((i*tpb) % 360, 3))
            rev.setRotation(round((i*tpb + mgroove) % 360, 3))
        for i in range(int(step_size) - 1):
            fwd, next_fwd = fpxis[i], fpxis[i + 1]
            j = (step_size - 1) - i
            rev, next_rev = rpxis[j], rpxis[j - 1]
            fwd.set3pItem(next_fwd)
            rev.set3pItem(next_rev)
            next_fwd.set5pItem(fwd)
            next_rev.set5pItem(rev)
    # end def

    def partCrossoverSpanAngle(self):
        """
        Returns:
            int: Crossover span angle from Part.
        """
        return self.virtual_helix_item.partCrossoverSpanAngle()

    def updateModelActiveBaseInfo(self, pre_xover_info):
        """Notify model of pre_xover_item hover state.
        """
        self.model_part.setActiveBaseInfo(pre_xover_info)
Beispiel #51
0
class DiagramScene(QGraphicsScene):
    InsertItem, InsertLine, InsertText, MoveItem  = range(4)

    itemInserted = pyqtSignal(DiagramItem)

    textInserted = pyqtSignal(QGraphicsTextItem)

    itemSelected = pyqtSignal(QGraphicsItem)

    def __init__(self, itemMenu, parent=None):
        super(DiagramScene, self).__init__(parent)

        self.myItemMenu = itemMenu
        self.myMode = self.MoveItem
        self.myItemType = DiagramItem.Step
        self.line = None
        self.textItem = None
        self.myItemColor = Qt.white
        self.myTextColor = Qt.black
        self.myLineColor = Qt.black
        self.myFont = QFont()

    def setLineColor(self, color):
        self.myLineColor = color
        if self.isItemChange(Arrow):
            item = self.selectedItems()[0]
            item.setColor(self.myLineColor)
            self.update()

    def setTextColor(self, color):
        self.myTextColor = color
        if self.isItemChange(DiagramTextItem):
            item = self.selectedItems()[0]
            item.setDefaultTextColor(self.myTextColor)

    def setItemColor(self, color):
        self.myItemColor = color
        if self.isItemChange(DiagramItem):
            item = self.selectedItems()[0]
            item.setBrush(self.myItemColor)

    def setFont(self, font):
        self.myFont = font
        if self.isItemChange(DiagramTextItem):
            item = self.selectedItems()[0]
            item.setFont(self.myFont)

    def setMode(self, mode):
        self.myMode = mode

    def setItemType(self, type):
        self.myItemType = type

    def editorLostFocus(self, item):
        cursor = item.textCursor()
        cursor.clearSelection()
        item.setTextCursor(cursor)

        if item.toPlainText():
            self.removeItem(item)
            item.deleteLater()

    def mousePressEvent(self, mouseEvent):
        if (mouseEvent.button() != Qt.LeftButton):
            return

        if self.myMode == self.InsertItem:
            item = DiagramItem(self.myItemType, self.myItemMenu)
            item.setBrush(self.myItemColor)
            self.addItem(item)
            item.setPos(mouseEvent.scenePos())
            self.itemInserted.emit(item)
        elif self.myMode == self.InsertLine:
            self.line = QGraphicsLineItem(QLineF(mouseEvent.scenePos(),
                    mouseEvent.scenePos()))
            self.line.setPen(QPen(self.myLineColor, 2))
            self.addItem(self.line)
        elif self.myMode == self.InsertText:
            textItem = DiagramTextItem()
            textItem.setFont(self.myFont)
            textItem.setTextInteractionFlags(Qt.TextEditorInteraction)
            textItem.setZValue(1000.0)
            textItem.lostFocus.connect(self.editorLostFocus)
            textItem.selectedChange.connect(self.itemSelected)
            self.addItem(textItem)
            textItem.setDefaultTextColor(self.myTextColor)
            textItem.setPos(mouseEvent.scenePos())
            self.textInserted.emit(textItem)

        super(DiagramScene, self).mousePressEvent(mouseEvent)

    def mouseMoveEvent(self, mouseEvent):
        if self.myMode == self.InsertLine and self.line:
            newLine = QLineF(self.line.line().p1(), mouseEvent.scenePos())
            self.line.setLine(newLine)
        elif self.myMode == self.MoveItem:
            super(DiagramScene, self).mouseMoveEvent(mouseEvent)

    def mouseReleaseEvent(self, mouseEvent):
        if self.line and self.myMode == self.InsertLine:
            startItems = self.items(self.line.line().p1())
            if len(startItems) and startItems[0] == self.line:
                startItems.pop(0)
            endItems = self.items(self.line.line().p2())
            if len(endItems) and endItems[0] == self.line:
                endItems.pop(0)

            self.removeItem(self.line)
            self.line = None

            if len(startItems) and len(endItems) and \
                    isinstance(startItems[0], DiagramItem) and \
                    isinstance(endItems[0], DiagramItem) and \
                    startItems[0] != endItems[0]:
                startItem = startItems[0]
                endItem = endItems[0]
                arrow = Arrow(startItem, endItem)
                arrow.setColor(self.myLineColor)
                startItem.addArrow(arrow)
                endItem.addArrow(arrow)
                arrow.setZValue(-1000.0)
                self.addItem(arrow)
                arrow.updatePosition()

        self.line = None
        super(DiagramScene, self).mouseReleaseEvent(mouseEvent)

    def isItemChange(self, type):
        for item in self.selectedItems():
            if isinstance(item, type):
                return True
        return False
class DiagramScene(QGraphicsScene):
    InsertItem, InsertLine, InsertText, MoveItem, DefaultMode = range(5)

    itemInserted = pyqtSignal(int)

    textInserted = pyqtSignal(QGraphicsTextItem)

    itemSelected = pyqtSignal(QGraphicsItem)

    def __init__(self, item_menu, parent=None):
        super(DiagramScene, self).__init__(parent)

        self.my_item_menu = item_menu
        self.my_mode = self.DefaultMode
        self.my_item_type = "channel"
        self.line = None
        self.text_item = None
        self.my_item_color = Qt.white
        self.my_text_color = Qt.black
        self.my_line_color = Qt.black
        self.my_font = QFont()
        self.m_drag_offset = 0
        self.m_dragged = None

    def set_line_color(self, color):
        self.my_line_color = color
        if self.is_item_changed(Arrow):
            item = self.selectedItems()[0]
            item.set_color(self.my_line_color)
            self.update()

    def set_text_color(self, color):
        self.my_text_color = color
        if self.is_item_changed(DiagramTextItem):
            item = self.selectedItems()[0]
            item.setDefaultTextColor(self.my_text_color)

    def set_item_color(self, color):
        self.my_item_color = color
        if self.is_item_changed(DiagramTextItem):
            item = self.selectedItems()[0]
            item.setBrush(self.my_item_color)

    def setFont(self, font):
        self.my_font = font
        if self.is_item_changed(DiagramTextItem):
            item = self.selectedItems()[0]
            item.setFont(self.my_font)

    def set_mode(self, mode):
        self.my_mode = mode

    def set_item_type(self, new_type):
        self.my_item_type = new_type

    def editor_lost_focus(self, item):
        if item:
            cursor = item.text_cursor()
            cursor.clearSelection()
            item.set_text_cursor(cursor)

            if item.to_plain_text():
                self.removeItem(item)
                item.delete_later()

    # noinspection PyArgumentList
    def insert_item(self, item_type=None, x=None, y=None, text=None):
        if not text:
            text, ok = QInputDialog.getText(QInputDialog(), 'Insert name', 'Enter new object name:')
            if not ok:  # TODO
                return
        item = FlumeObject(item_type, text).pictogram
        item.setBrush(self.my_item_color)
        self.addItem(item)
        item.setPos(x, y)
        return item

    def mousePressEvent(self, mouse_event):

        if mouse_event.button() != Qt.LeftButton:
            return
        if self.my_mode == self.InsertItem:
            x = mouse_event.scenePos().x()  # // 50 * 50
            y = mouse_event.scenePos().y()  # // 50 * 50
            item = self.insert_item(self.my_item_type, x, y)
            self.itemInserted.emit(item.flume_component)
        elif self.my_mode == self.InsertLine:
            self.line = QGraphicsLineItem(QLineF(mouse_event.scenePos(),
                                                 mouse_event.scenePos()))
            self.line.setPen(QPen(self.my_line_color, 2))
            self.addItem(self.line)
        elif self.my_mode == self.InsertText:
            text_item = DiagramTextItem()
            text_item.setFont(self.my_font)
            text_item.setTextInteractionFlags(Qt.TextEditorInteraction)
            text_item.setZValue(1000.0)
            text_item.lostFocus.connect(self.editor_lost_focus)
            # text_item.selectedChange.connect(self.itemSelected)
            self.addItem(text_item)
            text_item.setDefaultTextColor(self.my_text_color)
            text_item.setPos(mouse_event.scenePos())
            self.textInserted.emit(text_item)
        else:
            self.m_dragged = QGraphicsScene.itemAt(self, mouse_event.scenePos(), QTransform())
            if self.m_dragged:
                self.my_mode = self.MoveItem
                self.m_drag_offset = mouse_event.scenePos() - self.m_dragged.pos()

        super(DiagramScene, self).mousePressEvent(mouse_event)

    def mouseMoveEvent(self, mouse_event):
        if self.my_mode == self.InsertLine and self.line:
            new_line = QLineF(self.line.line().p1(), mouse_event.scenePos())
            self.line.setLine(new_line)
        elif self.my_mode == self.MoveItem:
            if self.m_dragged:
                self.m_dragged.setPos(mouse_event.scenePos() - self.m_drag_offset)
            super(DiagramScene, self).mouseMoveEvent(mouse_event)

    def mouseReleaseEvent(self, mouse_event):
        if self.line and self.my_mode == self.InsertLine:
            start_items = self.items(self.line.line().p1())
            if len(start_items) and start_items[0] == self.line:
                start_items.pop(0)
            end_items = self.items(self.line.line().p2())
            if len(end_items) and end_items[0] == self.line:
                end_items.pop(0)

            self.removeItem(self.line)
            self.line = None

            if len(start_items) and len(end_items) and isinstance(start_items[0], FlumeDiagramItem) and \
                    isinstance(end_items[0], FlumeDiagramItem) and start_items[0] != end_items[0]:
                start_item = start_items[0]
                end_item = end_items[0]

                self.add_arrow(start_item, end_item)

        self.line = None

        if self.m_dragged:
            x = mouse_event.scenePos().x()  # // 50 * 50
            y = mouse_event.scenePos().y()  # // 50 * 50
            self.m_dragged.setPos(x, y)
            self.m_dragged = None
            self.my_mode = self.DefaultMode

        super(DiagramScene, self).mouseReleaseEvent(mouse_event)

    def add_arrow(self, start_item, end_item):
        arrow = Arrow(start_item, end_item)
        arrow.set_color(self.my_line_color)
        start_item.add_arrow(arrow)
        end_item.add_arrow(arrow)
        arrow.setZValue(-1000.0)
        self.addItem(arrow)
        arrow.update_position()

    def is_item_changed(self, new_type):
        for item in self.selectedItems():
            if isinstance(item, new_type):
                return True
        return False
Beispiel #53
0
class RotaryDialHoverRegion(QGraphicsEllipseItem):
    def __init__(self, rect, parent=None):
        # setup DNA line
        super(QGraphicsEllipseItem, self).__init__(rect, parent)
        self._parent = parent
        self.setPen(QPen(Qt.NoPen))
        self.setBrush(_HOVER_BRUSH)
        self.setAcceptHoverEvents(True)

        # hover marker
        self._hoverLine = QGraphicsLineItem(-_ROTARY_DELTA_WIDTH/2, 0, _ROTARY_DELTA_WIDTH/2, 0, self)
        self._hoverLine.setPen(QPen(QColor(204, 0, 0), .5))
        self._hoverLine.hide()

        self._startPos = None
        self._startAngle = None  # save selection start
        self._clockwise = None
        self.dummy = RotaryDialDeltaItem(0, 0, parent)
        self.dummy.hide()

    def updateRect(self, rect):
        self.setRect(rect)

    def hoverEnterEvent(self, event):
        self.updateHoverLine(event)
        self._hoverLine.show()
    # end def

    def hoverMoveEvent(self, event):
        self.updateHoverLine(event)
    # end def

    def hoverLeaveEvent(self, event):
        self._hoverLine.hide()
    # end def

    def mousePressEvent(self, event):
        r = _RADIUS
        self.updateHoverLine(event)
        pos = self._hoverLine.pos()
        aX, aY, angle = self.snapPosToCircle(pos, r)
        if angle != None:
            self._startPos = QPointF(aX, aY)
            self._startAngle = self.updateHoverLine(event)
            self.dummy.updateAngle(self._startAngle, 0)
            self.dummy.show()
        # mark the start
        # f = QGraphicsEllipseItem(pX, pY, 2, 2, self)
        # f.setPen(QPen(Qt.NoPen))
        # f.setBrush(QBrush(QColor(204, 0, 0)))
    # end def

    def mouseMoveEvent(self, event):
        eventAngle = self.updateHoverLine(event)
        # Record initial direction before calling getSpanAngle
        if self._clockwise is None:
            self._clockwise = False if eventAngle > self._startAngle else True
        spanAngle = self.getSpanAngle(eventAngle)
        self.dummy.updateAngle(self._startAngle, spanAngle)
    # end def

    def mouseReleaseEvent(self, event):
        self.dummy.hide()
        endAngle = self.updateHoverLine(event)
        spanAngle = self.getSpanAngle(endAngle)
        old_angle = self._parent.virtualHelix().getProperty('eulerZ')
        new_angle = round((old_angle - spanAngle) % 360,0)
        self._parent.virtualHelix().setProperty('eulerZ', new_angle)

        # mark the end
        # x = self._hoverLine.x()
        # y = self._hoverLine.y()
        # f = QGraphicsEllipseItem(x, y, 6, 6, self)
        # f.setPen(QPen(Qt.NoPen))
        # f.setBrush(QBrush(QColor(204, 0, 0, 128)))
    # end def

    def updateHoverLine(self, event):
        """
        Moves red line to point (aX,aY) on RotaryDialLine closest to event.pos.
        Returns the angle of aX, aY, using the Qt arc coordinate system
        (0 = east, 90 = north, 180 = west, 270 = south).
        """
        r = _RADIUS
        aX, aY, angle = self.snapPosToCircle(event.pos(), r)
        if angle != None:
            self._hoverLine.setPos(aX, aY)
            self._hoverLine.setRotation(-angle)
        return angle
    # end def

    def snapPosToCircle(self, pos, radius):
        """Given x, y and radius, return x,y of nearest point on circle, and its angle"""
        pX = pos.x()
        pY = pos.y()
        cX = cY = radius
        vX = pX - cX
        vY = pY - cY
        magV = sqrt(vX*vX + vY*vY)
        if magV == 0:
            return (None, None, None)
        aX = cX + vX / magV * radius
        aY = cY + vY / magV * radius
        angle = (atan2(aY-cY, aX-cX))
        deg = -degrees(angle) if angle < 0 else 180+(180-degrees(angle))
        return (aX, aY, deg)
    # end def

    def getSpanAngle(self, angle):
        """
        Return the spanAngle angle by checking the initial direction of the selection.
        Selections that cross 0° must be handed as an edge case.
        """
        if self._clockwise: # spanAngle is negative
            if angle < self._startAngle:
                spanAngle = angle - self._startAngle
            else:
                spanAngle = -(self._startAngle + (360-angle))
        else: # counterclockwise, spanAngle is positive
            if angle > self._startAngle:
                spanAngle = angle - self._startAngle
            else:
                spanAngle = (360-self._startAngle) + angle
        return spanAngle