def shape(self): """generates outline for path """ qp = QPainterPathStroker() qp.setWidth(8) path = qp.createStroke(self.path()) return path
def shape(self): # return interactive path qp = QPainterPathStroker() qp.setWidth(8) # create outline of path path = qp.createStroke(self.path()) return path
def setAnchorPath(self, path): """ Set the anchor's curve path as a :class:`QPainterPath`. """ self.prepareGeometryChange() self.__boundingRect = None self.__anchorPath = path # Create a stroke of the path. stroke_path = QPainterPathStroker() stroke_path.setCapStyle(Qt.RoundCap) # Shape is wider (bigger mouse hit area - should be settable) stroke_path.setWidth(12) self.__shape = stroke_path.createStroke(path) # The full stroke stroke_path.setWidth(3) self.__fullStroke = stroke_path.createStroke(path) # The dotted stroke (when not connected to anything) stroke_path.setDashPattern(Qt.DotLine) self.__dottedStroke = stroke_path.createStroke(path) if self.anchored: self.setPath(self.__fullStroke) self.setBrush(self.connectedBrush) else: self.setPath(self.__dottedStroke) self.setBrush(self.normalBrush)
def _shapeFromPath(path, width): if path.isEmpty(): return path ps = QPainterPathStroker() ps.setWidth(width) p = ps.createStroke(path) p.addPath(path) return p
def shape(self) -> QPainterPath: rect = self.rect() path = QPainterPath() stroker = QPainterPathStroker() path.addRect(rect) stroker.setWidth(self.pen().width()) shape = stroker.createStroke(path) return shape
def shape(self): path = QPainterPath() stroker = QPainterPathStroker() path.moveTo(self.line().p1()) path.lineTo(self.line().p2()) path.addPolygon(self._arrow_head) path.addPolygon(self._arrow_tail) stroker.setWidth(self.pen().width()) return stroker.createStroke(path)
def stroke_path(path, pen): """Create a QPainterPath stroke from the `path` drawn with `pen`. """ stroker = QPainterPathStroker() stroker.setCapStyle(pen.capStyle()) stroker.setJoinStyle(pen.joinStyle()) stroker.setMiterLimit(pen.miterLimit()) stroker.setWidth(max(pen.widthF(), 1e-9)) return stroker.createStroke(path)
def shape(self): """ Reimplemented function to select outline only. @return: Returns the Outline only """ painterStrock = QPainterPathStroker() painterStrock.setCurveThreshold(0.01) painterStrock.setWidth(0) stroke = painterStrock.createStroke(self.path) return stroke
def shape(self) -> QPainterPath: rect = self.rect() path = QPainterPath() stroker = QPainterPathStroker() path.addEllipse(rect) stroker.setWidth(self.pen().width()) if self.isSelected(): path.addRect(QRectF(rect.topLeft(), QSizeF(5., 5.))) path.addRect(QRectF(rect.topRight() - QPointF(5., 0.), QSizeF(5., 5.))) path.addRect(QRectF(rect.bottomLeft() - QPointF(0., 5.), QSizeF(5., 5.))) path.addRect(QRectF(rect.bottomRight() - QPointF(5., 5.), QSizeF(5., 5.))) return stroker.createStroke(path)
def shape_from_path(self, path, pen): if path == QPainterPath() or pen == Qt.NoPen: return path ps = QPainterPathStroker() ps.setCapStyle(pen.capStyle()) ps.setWidth(pen.widthF()) ps.setJoinStyle(pen.joinStyle()) ps.setMiterLimit(pen.miterLimit()) p = ps.createStroke(path) p.addPath(path) return p
def shape(self): """Overrides shape method and set shape to segment on which grabber is located""" index = self.m_index # take start and end point of segment startPoint = QPointF(self.parentItem().points[index]) endPoint = QPointF(self.parentItem().points[index + 1]) # map in grabber's co-ordinate startPoint = self.mapFromParent(startPoint) endPoint = self.mapFromParent(endPoint) # create path as line path = QPainterPath(startPoint) path.lineTo(endPoint) # generate outlines for path stroke = QPainterPathStroker() stroke.setWidth(8) return stroke.createStroke(path)
def buildPath(self): srcPos, tarPos = self.getNodePos() if self.pathPnt and (self.pathPnt[0]-srcPos).manhattanLength() < 0.05 and (self.pathPnt[1]-tarPos).manhattanLength() < 0.05: return self.path self.pathPnt = (srcPos, tarPos) path = QtGui.QPainterPath() path.moveTo(srcPos) dx = tarPos.x() - srcPos.x() p1 = srcPos + QtCore.QPointF(dx*0.3, 0) p2 = tarPos + QtCore.QPointF(-dx*0.7, 0) path.cubicTo(p1,p2,tarPos) self.curve = QtGui.QPainterPath(path) self.path = path from PyQt5.QtGui import QPainterPathStroker stroker = QPainterPathStroker() stroker.setWidth(10.0) self.pathShape = stroker.createStroke(self.path) return path
def buildPath(self): srcPos, tarPos = self.getNodePos() if self.pathPnt and (self.pathPnt[0] - srcPos).manhattanLength( ) < 0.05 and (self.pathPnt[1] - tarPos).manhattanLength() < 0.05: return self.path self.pathPnt = (srcPos, tarPos) path = QtGui.QPainterPath() path.moveTo(srcPos) dx = tarPos.x() - srcPos.x() p1 = srcPos + QtCore.QPointF(dx * 0.3, 0) p2 = tarPos + QtCore.QPointF(-dx * 0.7, 0) path.cubicTo(p1, p2, tarPos) self.curve = QtGui.QPainterPath(path) self.path = path from PyQt5.QtGui import QPainterPathStroker stroker = QPainterPathStroker() stroker.setWidth(10.0) self.pathShape = stroker.createStroke(self.path) return path
def arrow_path_plain(line, width): """ Return an :class:`QPainterPath` of a plain looking arrow. """ path = QPainterPath() p1, p2 = line.p1(), line.p2() if p1 == p2: return path baseline = QLineF(line) # Require some minimum length. baseline.setLength(max(line.length() - width * 3, width * 3)) path.moveTo(baseline.p1()) path.lineTo(baseline.p2()) stroker = QPainterPathStroker() stroker.setWidth(width) path = stroker.createStroke(path) arrow_head_len = width * 4 arrow_head_angle = 50 line_angle = line.angle() - 180 angle_1 = line_angle - arrow_head_angle / 2.0 angle_2 = line_angle + arrow_head_angle / 2.0 points = [ p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(), p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2 ] poly = QPolygonF(points) path_head = QPainterPath() path_head.addPolygon(poly) path = path.united(path_head) return path
class PFSRelation(PFSElement): def __init__(self, id: str, source: PFSNode, target: PFSNode): PFSElement.__init__(self, id) self._source = source self._sourceNum = 0 self._target = target self._targetNum = 0 self._midPoints = [] self._firstPoint = None self._lastPoint = None self._pen = QPen(Qt.black) self._penSelected = QPen(PFSElement.SELECTED_PEN) self._penSelectedAlt = QPen(PFSElement.SELECTED_PEN_ALT) self._obj = PFSGraphItems() self.penEdited = self._obj.penEdited self._stroke = QPainterPathStroker() self._stroke.setWidth(20) def sceneEventFilter(self, item, ev: QEvent): print(ev.type()) return QGraphicsItem.sceneEventFilter(self, item, ev) def closestMiddlePoint(self, pos: QPointF): d = -1 p1 = None for p in self._midPoints: aux = QLineF(pos, p).length() if p1 is None or aux < d: p1 = p d = aux return p1 def closeMiddlePoint(self, pos: QPointF): for p in self._midPoints: if QLineF(pos, p).length() < 3: return p return None def closestPoint(self, pos: QPointF): d = -1 p = None p1 = self._firstPoint prev = -1 for i in range(len(self._midPoints)): p2 = self._midPoints[i] l = QLineF(p1, p2) x = QPointF.dotProduct(pos - p1, p2 - p1) / l.length() if x < 0: paux = p1 elif x > 1: paux = p2 else: paux = l.pointAt(x) aux = QLineF(paux, pos).length() if p is None or aux < d: p = paux d = aux prev = i p1 = p2 p2 = self._lastPoint l = QLineF(p1, p2) x = QPointF.dotProduct(pos - p1, p2 - p1) / (l.length() * l.length()) if x < 0: paux = p1 elif x > 1: paux = p2 else: paux = l.pointAt(x) aux = QLineF(paux, pos).length() if p is None or aux < d: p = paux d = aux prev = -1 return p, prev def addMiddlePoint(self, point: QPointF, i=-1): if i < 0: self._midPoints.append(point) else: self._midPoints.insert(i, point) def createMiddlePoint(self, pos: QPointF): p, i = self.closestPoint(pos) self.addMiddlePoint(p, i) self.scene().update() def moveX(self, txt, update=True): value = float(txt) for point in self._midPoints: point.setX(point.x() + value) if update: self.scene().update() def moveY(self, txt, update=True): value = float(txt) for point in self._midPoints: point.setY(point.y() + value) if update: self.scene().update() def simpleTree(self, parent): tree = PFSTreeItem(parent, [self._id], 0, QIcon(PFSRelationIcon())) tree.clicked.connect(self.selectSingle) return tree def tree(self, parent): tree = PFSTreeItem(parent, [self._id], 0, QIcon(PFSRelationIcon())) tree.clicked.connect(self.selectSingle) child = self._source.simpleTree(tree) child = self._target.simpleTree(tree) return tree def hasSubPage(self): return False def copy(self, x, y): ans = PFSRelationContent() ans._id = self._id ans._midPoints = [] for point in ans._midPoints: ans._midPoints.append(QPointF(point.x() - x, point.y() - y)) ans._pen = self._pen ans._tags = self._tags ans._source = self._source._id ans._target = self._target._id ans._sourceNum = self._sourceNum ans._targetNum = self._targetNum return ans def paste(content, id, dx, dy, itemList): ans = PFSRelation.createRelation(id, itemList[content._source], itemList[content._target]) ans._pen = content._pen ans._sourceNum = content._sourceNum ans._targetNum = content._targetNum for tag in content._tags: ans.addTag(tag._name, tag._use, False) for point in content._midPoints: ans._midPoints.append(QPointF(point.x() + dx, point.y() + dy)) ans.updatePoints() return ans def createRelation(id: str, source: PFSNode, target: PFSNode): if isinstance(source, PFSActive): if isinstance(target, PFSPassive): r = PFSRelation(id, source, target) source.changed.connect(r.updatePoints) target.changed.connect(r.updatePoints) source.deleted.connect(r.putInDelete) target.deleted.connect(r.putInDelete) return r elif isinstance(source, PFSPassive): if isinstance(target, PFSActive): r = PFSRelation(id, source, target) source.changed.connect(r.updatePoints) target.changed.connect(r.updatePoints) source.deleted.connect(r.putInDelete) target.deleted.connect(r.putInDelete) return r return None def updatePoints(self): if len(self._midPoints) == 0: if isinstance(self._source, PFSActive): self._firstPoint = self._source.getBestRelationPointOutput( QRect(self._target.x(), self._target.y(), self._target._width, self._target._height).center(), self._sourceNum) self._lastPoint = self._target.getBestRelationPointInput( self._firstPoint, self._targetNum) else: self._lastPoint = self._target.getBestRelationPointInput( QRect(self._source.x(), self._source.y(), self._source._width, self._source._height).center(), self._targetNum) self._firstPoint = self._source.getBestRelationPointOutput( self._lastPoint, self._sourceNum) else: self._firstPoint = self._source.getBestRelationPointOutput( self._midPoints[0], self._sourceNum) self._lastPoint = self._target.getBestRelationPointInput( self._midPoints[-1], self._targetNum) def getPath(self) -> QPainterPath: pol = QPolygonF() pol.append(self._firstPoint) for p in self._midPoints: pol.append(p) pol.append(self._lastPoint) ans = QPainterPath() ans.addPolygon(pol) return ans def shape(self) -> QPainterPath: return self._stroke.createStroke(self.getPath()) def paint(self, p: QPainter, o: QStyleOptionGraphicsItem, w: QWidget): p.setPen(self._pen) if self.isSelected(): if self._pen.color() == PFSElement.SELECTED_PEN: p.setPen(self._penSelectedAlt) else: p.setPen(self._penSelected) path = self.getPath() p.drawPath(path) if len(self._midPoints) == 0: ang = math.atan2(self._lastPoint.y() - self._firstPoint.y(), self._lastPoint.x() - self._firstPoint.x()) else: ang = math.atan2(self._lastPoint.y() - self._midPoints[-1].y(), self._lastPoint.x() - self._midPoints[-1].x()) p.save() p.translate(self._lastPoint) p.rotate(ang * 180 / math.pi) self.drawArrow(p) p.restore() def drawArrow(self, p: QPainter): p.drawLine(-10, -6, 0, 0) p.drawLine(-10, 6, 0, 0) def boundingRect(self): if self._firstPoint is None or self._lastPoint is None: self.updatePoints() t = min(self._firstPoint.y(), self._lastPoint.y()) b = max(self._firstPoint.y(), self._lastPoint.y()) l = min(self._firstPoint.x(), self._lastPoint.x()) r = max(self._firstPoint.x(), self._lastPoint.x()) for p in self._midPoints: if p.x() < l: l = p.x() if p.x() > r: r = p.x() if p.y() < t: t = p.y() if p.y() > b: b = p.y() w = r - l if w < 5: w = 5 h = b - t if h < 5: h = 5 return QRectF(l, t, w, h) def generateXml(self, xml: QXmlStreamWriter): PFSXmlBase.open(xml) xml.writeStartElement("relation") xml.writeAttribute("id", self._id) xml.writeAttribute("source", self._source._id) xml.writeAttribute("sourceport", str(self._sourceNum)) xml.writeAttribute("target", self._target._id) xml.writeAttribute("targetport", str(self._targetNum)) PFSXmlBase.graphicsArc(xml, self._midPoints, self._pen) PFSBasicElement.generateXml(self, xml) xml.writeEndElement() #fecha distributor PFSXmlBase.close(xml) def move(self, x, y): delta = QPointF(x, y) for p in self._midPoints: p += delta def createFromXml(node: QDomNode): if node.nodeName() != "relation": return None attr = node.attributes() if not (node.hasAttributes() and attr.contains("id")): return None id = attr.namedItem("id").nodeValue() if not (attr.contains("source") and attr.contains("target")): return None source = attr.namedItem("source").nodeValue() target = attr.namedItem("target").nodeValue() sourceNum = 0 targetNum = 0 if attr.contains("sourceport"): sourceNum = int(attr.namedItem("sourceport").nodeValue()) if attr.contains("targetport"): targetNum = int(attr.namedItem("targetport").nodeValue()) graphics = None tags = [] childs = node.childNodes() for i in range(childs.count()): child = childs.at(i) if child.nodeName() == "graphics": graphics = PFSXmlBase.getArc(child) if child.nodeName() == "tags": tags = PFSBasicElement.createFromXml(child) re = PFSRelationContent() re._id = id re._source = source re._sourceNum = sourceNum re._target = target re._targetNum = targetNum if graphics is not None and graphics.line is not None: re._pen = graphics.line re._midPoints = [] if graphics is not None and graphics.pos is not None: for pos in graphics.pos: re._midPoints.append(QPointF(pos.x, pos.y)) re._tags = tags return re def putInDelete(self): if self.scene() is not None: lst = self.scene()._itemsDeleted if self not in lst: lst.append(self) def setPenColor(self, color: QColor): self._pen.setColor(color) self.scene().update() def setPenStyle(self, style: Qt): self._pen.setStyle(style) self.scene().update() self.penEdited.emit(style) def setPenWidth(self, width: str): self._pen.setWidth(float(width)) self.scene().update() def setSourceNum(self, text: str): self._sourceNum = int(text) if self.scene() is not None: self.updatePoints() self.scene().update() def setTargetNum(self, text: str): self._targetNum = int(text) if self.scene() is not None: self.updatePoints() self.scene().update() def propertiesTable(self): ans = [] lblType = PFSTableLabel("Elemento") lblValue = PFSTableNormal("Arco") lblValue.setFlags(Qt.NoItemFlags) ans.append([lblType, lblValue]) lblType = PFSTableLabel("ID") lblValue = PFSTableNormal(self._id) lblValue.setFlags(Qt.NoItemFlags) ans.append([lblType, lblValue]) lblType = PFSTableLabel("Cor do contorno") lblValue = PFSTableValueButton(self._pen.color().name()) lblValue.clicked.connect(self.changeLineColor) ans.append([lblType, lblValue]) lblType = PFSTableLabel("Linha do contorno") lblValue = PFSTableValueCombo(self.PEN_LIST, self._pen.style()) self.penEdited.connect(lblValue.updateText) lblValue.currentTextChanged.connect(self.changeLineStyle) ans.append([lblType, lblValue]) lblType = PFSTableLabel("Espessura do contorno") lblValue = PFSTableValueText(str(self._pen.width())) lblValue.edited.connect(self.changeLineWidth) ans.append([lblType, lblValue]) lblType = PFSTableLabel("Porta origem") lblValue = PFSTableValueCombo( {str(x + 1): str(x) for x in range(self._source.outputNum())}, str(self._sourceNum)) lblValue.currentTextChanged.connect(self.changeSourceNum) ans.append([lblType, lblValue]) lblType = PFSTableLabel("Porta destino") lblValue = PFSTableValueCombo( {str(x + 1): str(x) for x in range(self._target.inputNum())}, str(self._targetNum)) lblValue.currentTextChanged.connect(self.changeTargetNum) ans.append([lblType, lblValue]) lblType = PFSTableLabelTags("Tags") lblValue = PFSTableValueBox(self._tags, self.createTag) ans.append([lblType, lblValue]) return ans def changeLineColor(self): color = QColorDialog.getColor(self._pen.color(), self.scene()._page._net, "Escolha a cor do contorno") if color.isValid() and color != self._pen.color(): x = PFSUndoPropertyButton(color, self._pen.color(), self.setPenColor) x.setText("Alterar cor") self.scene()._page._net.undoStack.push(x) def changeLineStyle(self, text): if text in self.PEN_LIST: x = PFSUndoPropertyCombo(self.PEN_LIST[text], self._pen.style(), self.setPenStyle) x.setText("Alterar linha") self.scene()._page._net.undoStack.push(x) def changeLineWidth(self, prop): x = PFSUndoPropertyText(prop, self.setPenWidth) x.setText("Alterar espessura") self.scene()._page._net.undoStack.push(x) def changeSourceNum(self, text): try: x = PFSUndoPropertyCombo(str(int(text) - 1), str(self._sourceNum), self.setSourceNum) x.setText("Alterar porta entrada") self.scene()._page._net.undoStack.push(x) except: pass def changeTargetNum(self, text): try: x = PFSUndoPropertyCombo(str(int(text) - 1), str(self._targetNum), self.setTargetNum) x.setText("Alterar porta saída") self.scene()._page._net.undoStack.push(x) except: pass
def shape(self): qp = QPainterPathStroker() qp.setWidth(10) qp.setCapStyle(Qt.SquareCap) return qp.createStroke(self.path())
def shape(self): # 设置宽度 这里用了100 很大 qps = QPainterPathStroker() qps.setWidth(100) return qps.createStroke(self.calc_path())
def shape(self): stroker = QPainterPathStroker() stroker.setWidth(Constants.connectionItemSize * 3) return stroker.createStroke(self.path())