def calculateForces(self): if not self.scene() or self.scene().mouseGrabberItem() is self: self.newPos = self.pos() return # Sum up all forces pushing this item away. xvel = 0.0 yvel = 0.0 for item in self.scene().items(): if not isinstance(item, Node): continue line = QLineF(self.mapFromItem(item, 0, 0), QPointF(0, 0)) dx = line.dx() dy = line.dy() l = 2.0 * (dx * dx + dy * dy) if l > 0: xvel += (dx * 150.0) / l yvel += (dy * 150.0) / l # Now subtract all forces pulling items together. #weight = (len(self.edgeList) + 1) * 100.0 for edge in self.edgeList: if edge.sourceNode() is self: pos = self.mapFromItem(edge.destNode(), 0, 0) else: weight = edge.weight * 6 pos = self.mapFromItem(edge.sourceNode(), 0, 0) xvel += pos.x() / weight yvel += pos.y() / weight if qAbs(xvel) < 0.1 and qAbs(yvel) < 0.1: xvel = yvel = 0.0 sceneRect = self.scene().sceneRect() self.newPos = self.pos() + QPointF(xvel, yvel) self.newPos.setX( min(max(self.newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)) self.newPos.setY( min(max(self.newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10))
def adjust(self): if not self.source or not self.dest: return line = QLineF(self.mapFromItem(self.source, 0, 0), self.mapFromItem(self.dest, 0, 0)) length = line.length() self.prepareGeometryChange() if length > 20.0: edgeOffset = QPointF((line.dx() * 10) / length, (line.dy() * 10) / length) self.sourcePoint = line.p1() + edgeOffset self.destPoint = line.p2() - edgeOffset else: self.sourcePoint = line.p1() self.destPoint = line.p1()
def paint(self, painter, option, widget): if not self.source or not self.dest: return # Draw the line itself. line = QLineF(self.sourcePoint, self.destPoint) if line.length() == 0.0: return palette = QPalette() self.setZValue(self.state) if self.state == 3: pen = QPen(Qt.red, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) if self.state == 2: pen = QPen(Qt.red, 2, Qt.DashLine, Qt.RoundCap, Qt.RoundJoin) elif self.state == 1: pen = QPen(palette.color(QPalette.Disabled, QPalette.WindowText), 0, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) elif self.state == 0: pen = QPen() pen.setBrush(QBrush(Qt.NoBrush)) painter.setPen(pen) painter.drawLine(line) angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = Edge.TwoPi - angle # draw arrowheads if self.state == 2 or self.state == 3: # Draw the arrows if there's enough room. sourceArrowP1 = self.sourcePoint + QPointF( math.sin(angle + Edge.Pi / 3) * self.arrowSize, math.cos(angle + Edge.Pi / 3) * self.arrowSize) sourceArrowP2 = self.sourcePoint + QPointF( math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize, math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize) destArrowP1 = self.destPoint + QPointF( math.sin(angle - Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi / 3) * self.arrowSize) destArrowP2 = self.destPoint + QPointF( math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize) painter.setPen( QPen(Qt.red, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.setBrush(QBrush(Qt.red, Qt.SolidPattern)) painter.drawPolygon( QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])) #painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2])) if self.state > 0 and self.source > self.dest: point = QPointF((self.sourcePoint.x() + self.destPoint.x()) / 2, (self.sourcePoint.y() + self.destPoint.y()) / 2) point = QPointF(point.x() + math.sin(angle) * 16, point.y() + math.cos(angle) * 16) painter.drawText(point, self.text)