Пример #1
0
    def reshape(self):
        ''' Update the shape of the edge (redefined function) '''
        path = QPainterPath()
        # If there is a starting point, draw a line to the first curve point
        if self.start_point:
            path.moveTo(self.source_connection.center)
            path.lineTo(self.bezier[0])
        else:
            path.moveTo(self.source_connection.center)
        # Loop over the curve points:
        for group in self.bezier[1:]:
            path.cubicTo(*[point.center for point in group])

        # If there is an ending point, draw a line to it
        if self.end_point:
            path.lineTo(self.end_connection.center)

        end_point = path.currentPosition()
        arrowhead = self.angle_arrow(path)
        path.lineTo(arrowhead[0])
        path.moveTo(end_point)
        path.lineTo(arrowhead[1])
        path.moveTo(end_point)
        try:
            # Add the transition label, if any (none for the START edge)
            font = QFont('arial', pointSize=8)
            metrics = QFontMetrics(font)
            label = self.edge.get('label', '') or ''
            lines = label.split('\n')
            width = metrics.width(max(lines)) # longest line
            height = metrics.height() * len(lines)
            # lp is the position of the center of the text
            pos = self.mapFromScene(*self.edge['lp'])
            if not self.text_label:
                self.text_label = QGraphicsTextItem(
                                 self.edge.get('label', ''), parent=self)
                self.text_label.setX(pos.x() - width / 2)
                self.text_label.setY(pos.y() - height / 2)
                self.text_label.setFont(font)
                # Make horizontal center alignment, as dot does
                self.text_label.setTextWidth(
                        self.text_label.boundingRect().width())
                fmt = QTextBlockFormat()
                fmt.setAlignment(Qt.AlignHCenter)
                cursor = self.text_label.textCursor()
                cursor.select(QTextCursor.Document)
                cursor.mergeBlockFormat(fmt)
                cursor.clearSelection()
                self.text_label.setTextCursor(cursor)
                self.text_label.show()
        except KeyError:
            # no label
            pass
        self.setPath(path)
Пример #2
0
    def reshape(self):
        ''' Update the shape of the edge (redefined function) '''
        path = QPainterPath()
        # If there is a starting point, draw a line to the first curve point
        if self.start_point:
            path.moveTo(self.source_connection.center)
            path.lineTo(self.bezier[0])
        else:
            path.moveTo(self.source_connection.center)
        # Loop over the curve points:
        for group in self.bezier[1:]:
            path.cubicTo(*[point.center for point in group])

        # If there is an ending point, draw a line to it
        if self.end_point:
            path.lineTo(self.end_connection.center)

        end_point = path.currentPosition()
        arrowhead = self.angle_arrow(path)
        path.lineTo(arrowhead[0])
        path.moveTo(end_point)
        path.lineTo(arrowhead[1])
        path.moveTo(end_point)
        try:
            # Add the transition label, if any (none for the START edge)
            font = QFont('arial', pointSize=8)
            metrics = QFontMetrics(font)
            label = self.edge.get('label', '') or ''
            lines = label.split('\n')
            width = metrics.width(max(lines))  # longest line
            height = metrics.height() * len(lines)
            # lp is the position of the center of the text
            pos = self.mapFromScene(*self.edge['lp'])
            if not self.text_label:
                self.text_label = QGraphicsTextItem(self.edge.get('label', ''),
                                                    parent=self)
                self.text_label.setX(pos.x() - width / 2)
                self.text_label.setY(pos.y() - height / 2)
                self.text_label.setFont(font)
                # Make horizontal center alignment, as dot does
                self.text_label.setTextWidth(
                    self.text_label.boundingRect().width())
                fmt = QTextBlockFormat()
                fmt.setAlignment(Qt.AlignHCenter)
                cursor = self.text_label.textCursor()
                cursor.select(QTextCursor.Document)
                cursor.mergeBlockFormat(fmt)
                cursor.clearSelection()
                self.text_label.setTextCursor(cursor)
                self.text_label.show()
        except KeyError:
            # no label
            pass
        self.setPath(path)
Пример #3
0
    def updatePath(self):
        path = QPainterPath()
        path.moveTo(self.pos1)

        dx = self.pos2.x() - self.pos1.x()
        dy = self.pos2.y() - self.pos1.y()

        ctr1 = QPointF(self.pos1.x() + dx * 0.25, self.pos1.y() + dy * 0.1)
        ctr2 = QPointF(self.pos1.x() + dx * 0.75, self.pos1.y() + dy * 0.9)

        path.cubicTo(ctr1, ctr2, self.pos2)
        self.setPath(path)
Пример #4
0
    def updatePath(self):
        path = QPainterPath()
        path.moveTo(self.pos1)

        dx = self.pos2.x() - self.pos1.x()
        dy = self.pos2.y() - self.pos1.y()

        ctr1 = QPointF(self.pos1.x() + dx * 0.25, self.pos1.y() + dy * 0.1)
        ctr2 = QPointF(self.pos1.x() + dx * 0.75, self.pos1.y() + dy * 0.9)

        path.cubicTo(ctr1, ctr2, self.pos2)
        self.setPath(path)
    def subPathList(self):
        """
        TOWRITE

        :rtype: QList<QPainterPath>
        """
        s = self.scale()  # qreal
        trans = QTransform()
        trans.rotate(self.rotation())
        trans.scale(s, s)

        ## QList<QPainterPath> pathList;
        pathList = []
        path = self.objTextPath  # QPainterPath

        element = QPainterPath.Element
        pathMoves = []  # QList<int>
        numMoves = 0  # int

        for i in range(0, path.elementCount()):  # for(int i = 0; i < path.elementCount(); i++)

            element = path.elementAt(i)
            if element.isMoveTo():

                pathMoves.append(i)  # pathMoves << i;
                numMoves += 1  # numMoves++;

        pathMoves.append(path.elementCount())  # pathMoves << path.elementCount();

        for p in range(0, len(pathMoves) - 1):  #  for(int p = 0; p < pathMoves.size()-1 && p < numMoves; p++)
            if not (p < numMoves):
                break

            subPath = QPainterPath()
            for i in range(pathMoves[p], pathMoves[p + 1]):  # for(int i = pathMoves.value(p); i < pathMoves.value(p+1); i++)

                element = path.elementAt(i)
                if element.isMoveTo():
                    subPath.moveTo(element.x, element.y)

                elif element.isLineTo():
                    subPath.lineTo(element.x, element.y)

                elif element.isCurveTo():
                    subPath.cubicTo(path.elementAt(i).x, path.elementAt(i).y,          # control point 1
                                    path.elementAt(i + 1).x, path.elementAt(i + 1).y,  # control point 2
                                    path.elementAt(i + 2).x, path.elementAt(i + 2).y)  # end point

            pathList.append(trans.map(subPath))

        return pathList
Пример #6
0
 def paint(self, painter, styleOption, widget):
   ''' Reimplemented to paint elements in alternating colors '''
   path = self.path()  # alias
   pathEnd = None
   i = 0
   while True:
     try:
       element = path.elementAt(i)
       # print type(element), element.type
       if element.isMoveTo():
         pathEnd = QPointF(element.x, element.y)
         i+=1
       elif element.isCurveTo():
         # Gather curve data, since is spread across elements of type curveElementData
         cp1 = QPointF(element.x, element.y)
         element = path.elementAt(i+1)
         cp2 = QPointF(element.x, element.y)
         element = path.elementAt(i+2)
         newEnd = QPointF(element.x, element.y)
         # create a subpath, since painter has no drawCubic method
         subpath=QPainterPath()
         subpath.moveTo(pathEnd)
         subpath.cubicTo(cp1, cp2, newEnd)
         painter.drawPath(subpath)
         
         pathEnd = newEnd
         i+=3
       else:
         print "unhandled path element", element.type
         i+=1
         """
         TODO: if SegmentStringss contain lines (w/o Direction ControlPoints)
         !!! We don't use QPathElements of type Line
         elif element.isLineTo():
           newEnd = QPointF(element.x, element.y)
           painter.drawLine(pathEnd, newEnd)
           pathEnd = newEnd
           i+=1
         """
       if i >= path.elementCount():
         break
     except Exception as inst:
       print inst
       break
       
     # Alternate colors
     if i%2 == 1:
       painter.setPen(Qt.blue)
     else:
       painter.setPen(Qt.red)
    def subPathList(self):
        """
        TOWRITE

        :rtype: QList<QPainterPath>
        """
        s = self.scale()  # qreal
        trans = QTransform()
        trans.rotate(self.rotation())
        trans.scale(s, s)

        ## QList<QPainterPath> pathList;
        pathList = []
        path = objTextPath  # QPainterPath

        element = QPainterPath.Element
        pathMoves = []  # QList<int>
        numMoves = 0  # int

        for i in range(0, path.elementCount()):  # for(int i = 0; i < path.elementCount(); i++)

            element = path.elementAt(i)
            if element.isMoveTo():

                pathMoves.append(i)  # pathMoves << i;
                numMoves += 1 # numMoves++;

        pathMoves.append(path.elementCount())  # pathMoves << path.elementCount();

        for p in range(0, pathMoves.size() - 1 and numMoves):  #  for(int p = 0; p < pathMoves.size()-1 && p < numMoves; p++)

            subPath = QPainterPath()
            for i in range(pathMoves.value(p), pathMoves.value(p + 1)):  # for(int i = pathMoves.value(p); i < pathMoves.value(p+1); i++)

                element = path.elementAt(i)
                if element.isMoveTo():
                    subPath.moveTo(element.x, element.y)

                elif element.isLineTo():
                    subPath.lineTo(element.x, element.y)

                elif element.isCurveTo():
                    subPath.cubicTo(path.elementAt(i).x, path.elementAt(i).y,          # control point 1
                                    path.elementAt(i + 1).x, path.elementAt(i + 1).y,  # control point 2
                                    path.elementAt(i + 2).x, path.elementAt(i + 2).y)  # end point

            pathList.append(trans.map(subPath))

        return pathList
Пример #8
0
 def draw_edge(self, painter, option, edge, lane_offset):
     from_y = 0.5 + lane_offset
     to_y = 1 + from_y
     pen = QPen(self.edge_color(edge.color), self.edge_thickness,
         Qt.SolidLine, Qt.FlatCap, Qt.RoundJoin)
     painter.setPen(pen)
     if edge.from_lane == edge.to_lane:
         line_x = edge.from_lane + 0.5
         painter.drawLine(QPointF(line_x, from_y), QPointF(line_x, to_y))
     else:
         from_x = edge.from_lane + 0.5
         to_x = edge.to_lane + 0.5
         path = QPainterPath()
         path.moveTo(QPointF(from_x, from_y))
         path.cubicTo(from_x, from_y + 0.5, to_x, to_y - 0.5, to_x, to_y)
         painter.drawPath(path)
Пример #9
0
    def reshape(self):
        ''' Update the shape of the edge (redefined function) '''
        path = QPainterPath()
        # If there is a starting point, draw a line to the first curve point
        if self.start_point:
            path.moveTo(self.source_connection.center)
            path.lineTo(self.bezier[0])
        else:
            path.moveTo(self.source_connection.center)
        # Loop over the curve points:
        for group in self.bezier[1:]:
            path.cubicTo(*[point.center for point in group])

        # If there is an ending point, draw a line to it
        if self.end_point:
            path.lineTo(self.end_connection.center)

        end_point = path.currentPosition()
        arrowhead = self.angle_arrow(path)
        path.lineTo(arrowhead[0])
        path.moveTo(end_point)
        path.lineTo(arrowhead[1])
        path.moveTo(end_point)
        try:
            # Add the transition label, if any (none for the START edge)
            font = QFont('arial', pointSize=8)
            width = QFontMetrics(font).width(
                    self.edge.get('label', 0))
            pos = self.mapFromScene(*self.edge['lp'])
            #path.addText(pos.x() - width/2, pos.y(),
            #        font, self.edge['label'])
            if not self.text_label:
                self.text_label = QGraphicsTextItem(
                                 self.edge.get('label', ''), parent=self)
            self.text_label.setX(pos.x() - width / 2)
            self.text_label.setY(pos.y())
            self.text_label.setFont(font)
            self.text_label.show()
        except KeyError:
            # no label
            pass
        self.setPath(path)
Пример #10
0
    def reshape(self):
        ''' Update the shape of the edge (redefined function) '''
        path = QPainterPath()
        # If there is a starting point, draw a line to the first curve point
        if self.start_point:
            path.moveTo(self.source_connection.center)
            path.lineTo(self.bezier[0])
        else:
            path.moveTo(self.source_connection.center)
        # Loop over the curve points:
        for group in self.bezier[1:]:
            path.cubicTo(*[point.center for point in group])

        # If there is an ending point, draw a line to it
        if self.end_point:
            path.lineTo(self.end_connection.center)

        end_point = path.currentPosition()
        arrowhead = self.angle_arrow(path)
        path.lineTo(arrowhead[0])
        path.moveTo(end_point)
        path.lineTo(arrowhead[1])
        path.moveTo(end_point)
        try:
            # Add the transition label, if any (none for the START edge)
            font = QFont('arial', pointSize=8)
            width = QFontMetrics(font).width(self.edge.get('label', 0))
            pos = self.mapFromScene(*self.edge['lp'])
            #path.addText(pos.x() - width/2, pos.y(),
            #        font, self.edge['label'])
            if not self.text_label:
                self.text_label = QGraphicsTextItem(self.edge.get('label', ''),
                                                    parent=self)
            self.text_label.setX(pos.x() - width / 2)
            self.text_label.setY(pos.y())
            self.text_label.setFont(font)
            self.text_label.show()
        except KeyError:
            # no label
            pass
        self.setPath(path)
Пример #11
0
    def setObjectText(self, strng):
        """
        TOWRITE

        :param `strng`: TOWRITE
        :type `strng`: QString
        """
        self.objText = strng
        textPath = QPainterPath()
        font = QFont()
        font.setFamily(self.objTextFont)
        font.setPointSizeF(self.objTextSize)
        font.setBold(self.objTextBold)
        font.setItalic(self.objTextItalic)
        font.setUnderline(self.objTextUnderline)
        font.setStrikeOut(self.objTextStrikeOut)
        font.setOverline(self.objTextOverline)
        textPath.addText(0., 0., font, strng)

        # Translate the path based on the justification.
        jRect = textPath.boundingRect()  # QRectF
        if self.objTextJustify == "Left": textPath.translate(-jRect.left(), 0)
        elif self.objTextJustify == "Center":
            textPath.translate(-jRect.center().x(), 0)
        elif self.objTextJustify == "Right":
            textPath.translate(-jRect.right(), 0)
        elif self.objTextJustify == "Aligned":
            pass  # TODO: TextSingleObject Aligned Justification
        elif self.objTextJustify == "Middle":
            textPath.translate(-jRect.center())
        elif self.objTextJustify == "Fit":
            pass  # TODO: TextSingleObject Fit Justification
        elif self.objTextJustify == "Top Left":
            textPath.translate(-jRect.topLeft())
        elif self.objTextJustify == "Top Center":
            textPath.translate(-jRect.center().x(), -jRect.top())
        elif self.objTextJustify == "Top Right":
            textPath.translate(-jRect.topRight())
        elif self.objTextJustify == "Middle Left":
            textPath.translate(-jRect.left(), -jRect.top() / 2.0)
        elif self.objTextJustify == "Middle Center":
            textPath.translate(-jRect.center().x(), -jRect.top() / 2.0)
        elif self.objTextJustify == "Middle Right":
            textPath.translate(-jRect.right(), -jRect.top() / 2.0)
        elif self.objTextJustify == "Bottom Left":
            textPath.translate(-jRect.bottomLeft())
        elif self.objTextJustify == "Bottom Center":
            textPath.translate(-jRect.center().x(), -jRect.bottom())
        elif self.objTextJustify == "Bottom Right":
            textPath.translate(-jRect.bottomRight())

        # Backward or Upside Down.
        if self.objTextBackward or self.objTextUpsideDown:

            horiz = 1.0  # qreal
            vert = 1.0  # qreal
            if self.objTextBackward:
                horiz = -1.0
            if self.objTextUpsideDown:
                vert = -1.0

            flippedPath = QPainterPath()

            element = QPainterPath.Element
            P2 = QPainterPath.Element
            P3 = QPainterPath.Element
            P4 = QPainterPath.Element
            for i in range(0, textPath.elementCount(
            )):  # for(int i = 0; i < textPath.elementCount(); ++i)

                element = textPath.elementAt(i)
                if element.isMoveTo():
                    flippedPath.moveTo(horiz * element.x, vert * element.y)

                elif element.isLineTo():
                    flippedPath.lineTo(horiz * element.x, vert * element.y)

                elif element.isCurveTo():
                    # start point P1 is not needed
                    P2 = textPath.elementAt(i)  # control point
                    P3 = textPath.elementAt(i + 1)  # control point
                    P4 = textPath.elementAt(i + 2)  # end point

                    flippedPath.cubicTo(horiz * P2.x, vert * P2.y,
                                        horiz * P3.x, vert * P3.y,
                                        horiz * P4.x, vert * P4.y)

            objTextPath = flippedPath

        else:
            objTextPath = textPath

        # Add the grip point to the shape path.
        gripPath = objTextPath  # QPainterPath
        gripPath.connectPath(objTextPath)
        gripPath.addRect(-0.00000001, -0.00000001, 0.00000002, 0.00000002)
        self.setObjectPath(gripPath)
Пример #12
0
    def request_relayout(self):

        if self.graph is None:
            return

        # remove all edges
        for p in self._edge_paths:
            self.scene.removeItem(p)

        # remove all nodes
        self.remove_all_children()
        self._edge_paths = []

        g = pygraphviz.AGraph(directed=True)
        g.graph_attr['nodesep'] = 100
        g.graph_attr['ranksep'] = 50
        g.node_attr['shape'] = 'rect'

        for node in self.graph.nodes_iter():
            scene_proxy = self._proxy(node)
            size = node.size()
            width, height = size.width(), size.height()
            scene_proxy.setGeometry(QRectF(0.0, 0.0, width, height))
            g.add_node(node, width=width, height=height)

        for from_, to in self.graph.edges_iter():
            g.add_edge(from_, to)

        g.layout(prog='dot')

        for node in self.graph.nodes_iter():
            scene_proxy = self._proxies[node]
            n = g.get_node(node)
            center_x, center_y = (-float(v) / 72.0
                                  for v in n.attr['pos'].split(','))
            size = node.size()
            width, height = size.width(), size.height()
            x = center_x - (width / 2.0)
            y = center_y - (height / 2.0)
            scene_proxy.setPos(x, y)

        for from_, to in self.graph.edges_iter():
            edge = g.get_edge(from_, to)
            # TODO: look at below code
            all_points = [
                tuple(-float(v) / 72.0 for v in t.strip('e,').split(','))
                for t in edge.attr['pos'].split(' ')
            ]
            arrow = all_points[0]
            start_point = all_points[1]

            painter = QPainterPath(QPointF(*start_point))
            for c1, c2, end in grouper(all_points[2:], 3):
                painter.cubicTo(QPointF(*c1), QPointF(*c2), QPointF(*end))

            self._edge_paths.append(self.scene.addPath(painter))

        rect = self.scene.itemsBoundingRect()
        # Enlarge the rect so there is enough room at right and bottom
        rect.setX(rect.x() - self.LEFT_PADDING)
        rect.setY(rect.y() - self.TOP_PADDING)
        rect.setWidth(rect.width() + 2 * self.LEFT_PADDING)
        rect.setHeight(rect.height() + 2 * self.TOP_PADDING)

        self.scene.setSceneRect(rect)
        self.viewport().update()

        if self.selected is not None:
            self.show_selected()
        else:
            self.show_any()
    def setObjectText(self, strng):
        """
        TOWRITE

        :param `strng`: TOWRITE
        :type `strng`: QString
        """
        self.objText = strng
        textPath = QPainterPath()
        font = QFont()
        font.setFamily(self.objTextFont)
        font.setPointSizeF(self.objTextSize)
        font.setBold(self.objTextBold)
        font.setItalic(self.objTextItalic)
        font.setUnderline(self.objTextUnderline)
        font.setStrikeOut(self.objTextStrikeOut)
        font.setOverline(self.objTextOverline)
        textPath.addText(0., 0., font, strng)

        # Translate the path based on the justification.
        jRect = textPath.boundingRect()  # QRectF
        if   self.objTextJustify == "Left":          textPath.translate(-jRect.left(), 0)
        elif self.objTextJustify == "Center":        textPath.translate(-jRect.center().x(), 0)
        elif self.objTextJustify == "Right":         textPath.translate(-jRect.right(), 0)
        elif self.objTextJustify == "Aligned":       pass # TODO: TextSingleObject Aligned Justification
        elif self.objTextJustify == "Middle":        textPath.translate(-jRect.center())
        elif self.objTextJustify == "Fit":           pass # TODO: TextSingleObject Fit Justification
        elif self.objTextJustify == "Top Left":      textPath.translate(-jRect.topLeft())
        elif self.objTextJustify == "Top Center":    textPath.translate(-jRect.center().x(), -jRect.top())
        elif self.objTextJustify == "Top Right":     textPath.translate(-jRect.topRight())
        elif self.objTextJustify == "Middle Left":   textPath.translate(-jRect.left(), -jRect.top()/2.0)
        elif self.objTextJustify == "Middle Center": textPath.translate(-jRect.center().x(), -jRect.top()/2.0)
        elif self.objTextJustify == "Middle Right":  textPath.translate(-jRect.right(), -jRect.top()/2.0)
        elif self.objTextJustify == "Bottom Left":   textPath.translate(-jRect.bottomLeft())
        elif self.objTextJustify == "Bottom Center": textPath.translate(-jRect.center().x(), -jRect.bottom())
        elif self.objTextJustify == "Bottom Right":  textPath.translate(-jRect.bottomRight())

        # Backward or Upside Down.
        if self.objTextBackward or self.objTextUpsideDown:

            horiz = 1.0  # qreal
            vert = 1.0   # qreal
            if self.objTextBackward:
                horiz = -1.0
            if self.objTextUpsideDown:
                vert = -1.0

            flippedPath = QPainterPath()

            element = QPainterPath.Element
            P2      = QPainterPath.Element
            P3      = QPainterPath.Element
            P4      = QPainterPath.Element
            for i in range(0, textPath.elementCount()):  # for(int i = 0; i < textPath.elementCount(); ++i)

                element = textPath.elementAt(i)
                if element.isMoveTo():
                    flippedPath.moveTo(horiz * element.x, vert * element.y)

                elif element.isLineTo():
                    flippedPath.lineTo(horiz * element.x, vert * element.y)

                elif element.isCurveTo():
                                                    # start point P1 is not needed
                    P2 = textPath.elementAt(i)      # control point
                    P3 = textPath.elementAt(i + 1)  # control point
                    P4 = textPath.elementAt(i + 2)  # end point

                    flippedPath.cubicTo(horiz * P2.x, vert * P2.y,
                                        horiz * P3.x, vert * P3.y,
                                        horiz * P4.x, vert * P4.y)

            objTextPath = flippedPath

        else:
            objTextPath = textPath

        # Add the grip point to the shape path.
        gripPath = objTextPath  # QPainterPath
        gripPath.connectPath(objTextPath)
        gripPath.addRect(-0.00000001, -0.00000001, 0.00000002, 0.00000002)
        self.setObjectPath(gripPath)