def updatePath(self): if self.startGSocket: self._x1 = self.startGSocket.scenePos().x() self._y1 = self.startGSocket.scenePos().y() elif self.startPosition: self._x1 = self.startPosition.x() self._y1 = self.startPosition.y() else: return False if self.endGSocket: self._x2 = self.endGSocket.scenePos().x() self._y2 = self.endGSocket.scenePos().y() elif self.endPosition: self._x2 = self.endPosition.x() self._y2 = self.endPosition.y() else: return False print('edge position', self._x1, self._y1, '>>>', self._x2, self._y2) if self._x1 < self._x2: xc1, yc1 = (self._x1 + self._x2) / 2, self._y1 xc2, yc2 = (self._x1 + self._x2) / 2, self._y2 else: xc1, yc1 = (self._x1 + 120), self._y1 xc2, yc2 = (self._x2 - 120), self._y2 path = QPainterPath(QPointF(self._x1, self._y1)) path.cubicTo(QPointF(xc1, yc1), QPointF(xc2, yc2), QPointF(self._x2, self._y2)) self.setPath(path) return True
def paintEvent(self, event): rect = QRect(10, 20, 80, 60) path = QPainterPath() path.moveTo(20, 80) path.lineTo(20, 30) path.cubicTo(80, 0, 50, 50, 80, 80) startAngle = 30 * 16 arcLength = 120 * 16 painter = QPainter(self) painter.setPen(self.pen) painter.setBrush(self.brush) if self.antialiased: painter.setRenderHint(QPainter.Antialiasing) for x in range(0, self.width(), 100): for y in range(0, self.height(), 100): painter.save() painter.translate(x, y) if self.transformed: painter.translate(50, 50) painter.rotate(60.0) painter.scale(0.6, 0.9) painter.translate(-50, -50) if self.shape == RenderArea.Line: painter.drawLine(rect.bottomLeft(), rect.topRight()) elif self.shape == RenderArea.Points: painter.drawPoints(RenderArea.points) elif self.shape == RenderArea.Polyline: painter.drawPolyline(RenderArea.points) elif self.shape == RenderArea.Polygon: painter.drawPolygon(RenderArea.points) elif self.shape == RenderArea.Rect: painter.drawRect(rect) elif self.shape == RenderArea.RoundedRect: painter.drawRoundedRect(rect, 25, 25, Qt.RelativeSize) elif self.shape == RenderArea.Ellipse: painter.drawEllipse(rect) elif self.shape == RenderArea.Arc: painter.drawArc(rect, startAngle, arcLength) elif self.shape == RenderArea.Chord: painter.drawChord(rect, startAngle, arcLength) elif self.shape == RenderArea.Pie: painter.drawPie(rect, startAngle, arcLength) elif self.shape == RenderArea.Path: painter.drawPath(path) elif self.shape == RenderArea.Text: painter.drawText(rect, Qt.AlignCenter, "PyQt by\nRiverbank Computing") elif self.shape == RenderArea.Pixmap: painter.drawPixmap(10, 10, self.pixmap) painter.restore() painter.setPen(self.palette().dark().color()) painter.setBrush(Qt.NoBrush) painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1))
def update(self, eventPos, fase, point=None): # If user is setting the final point if fase == 1: path = QPainterPath() path.moveTo(self.initialPoint.position) path.lineTo(eventPos) self.setPath(path) if point: self.finalPoint = point # If user is setting ctrlPoint1 elif fase == 2: path = QPainterPath() path.moveTo(self.initialPoint.position) path.quadTo(eventPos, self.finalPoint.position) self.setPath(path) if point: self.ctrlPoint1 = point # If user is finishing the path (setting ctrlPoint2) elif fase == 3: path = QPainterPath() path.moveTo(self.initialPoint.position) path.cubicTo(self.ctrlPoint1.position, eventPos, self.finalPoint.position) self.setPath(path) if point: self.ctrlPoint2 = point
def paintEvent(self, event: QPaintEvent): with QPainter(self) as painter: painter.setRenderHint(QPainter.Antialiasing, True) painter.setPen(self.linePen) rect = self.lblRoot.geometry().translated(0, 2) # Draw the underline width = self.lblRoot.fontMetrics().boundingRect( self.lblRoot.text()).width() p = rect.bottomLeft() p += QPoint(width, 0) painter.drawLine(rect.bottomLeft(), p) # Draw Bezier curves to the child nodes for child in self.children: childBottomLeft: QPoint = child.mapToParent( child.lblRoot.geometry().bottomLeft()) childBottomLeft += QPoint(0, 2) cpX = rect.right() + int( (childBottomLeft.x() - rect.right()) / 2) start = QPoint(rect.bottomRight()) cp1 = QPoint(cpX, rect.bottom()) cp2 = QPoint(cpX, childBottomLeft.y()) end = QPoint(childBottomLeft) path = QPainterPath() path.moveTo(start) path.cubicTo(cp1, cp2, end) painter.drawPath(path)
def calcPath(self): """Compute bezier curves from source to destination""" s = self.owner.posSource d = self.owner.posDestination dist = (d[0] - s[0]) * 0.5 # Compute control point cpx_s = +dist cpx_d = -dist cpy_s = 0 cpy_d = 0 if self.owner.edge.start_socket is not None: ssin = self.owner.edge.start_socket.is_input ssout = self.owner.edge.start_socket.is_output sspos = self.owner.edge.start_socket.position if (s[0] > d[0] and ssout) or (s[0] < d[0] and ssin): cpx_d *= -1 cpx_s *= -1 cpy_d = ((s[1] - d[1]) / (math.fabs(s[1] - d[1]) + 1e-8)) * EDGE_CP_ROUNDNESS cpy_s = ((d[1] - s[1]) / (math.fabs(s[1] - d[1]) + 1e-8)) * EDGE_CP_ROUNDNESS path = QPainterPath( QPointF(self.owner.posSource[0], self.owner.posSource[1])) path.cubicTo(s[0] + cpx_s, s[1] + cpy_s, d[0] + cpx_d, d[1] + cpy_d, self.owner.posDestination[0], self.owner.posDestination[1]) return path
def drawGlyph(self, scene, glyph, offsetX=0, offsetY=0, color=(255, 255, 255)): path = QPainterPath() path.setFillRule(Qt.WindingFill) for c in self.decomposedPaths(glyph): segs = c.segments path.moveTo(segs[-1].points[-1].x, segs[-1].points[-1].y) for seg in segs: tuples = [(a.x, a.y) for a in seg.points] flattuples = list(sum(tuples, ())) if len(tuples) == 2: path.quadTo(*flattuples) elif len(tuples) == 3: path.cubicTo(*flattuples) else: path.lineTo(*flattuples) line = QGraphicsPathItem() line.setBrush(QColor(*color)) p = QPen() p.setStyle(Qt.NoPen) line.setPen(p) line.setPath(path) reflect = QTransform(1, 0, 0, -1, 0, 0) reflect.translate(offsetX, offsetY) # print(f"Drawing {glyph} at offset {offsetX} {offsetY}") line.setTransform(reflect) scene.addItem(line)
def __updateCurve(self): self.prepareGeometryChange() self.__boundingRect = None if self.sourceAnchor and self.sinkAnchor: source_pos = self.sourceAnchor.anchorScenePos() sink_pos = self.sinkAnchor.anchorScenePos() source_pos = self.curveItem.mapFromScene(source_pos) sink_pos = self.curveItem.mapFromScene(sink_pos) # Adaptive offset for the curve control points to avoid a # cusp when the two points have the same y coordinate # and are close together delta = source_pos - sink_pos dist = math.sqrt(delta.x()**2 + delta.y()**2) cp_offset = min(dist / 2.0, 60.0) # TODO: make the curve tangent orthogonal to the anchors path. path = QPainterPath() path.moveTo(source_pos) path.cubicTo(source_pos + QPointF(cp_offset, 0), sink_pos - QPointF(cp_offset, 0), sink_pos) self.curveItem.setPath(path) self.sourceIndicator.setPos(source_pos) self.sinkIndicator.setPos(sink_pos) self.__updateText() else: self.setHoverState(False) self.curveItem.setPath(QPainterPath())
def tailPath(self): path = QPainterPath() path.moveTo(self._points[-1].pos()) line = self.tailLine() u = line.p2() - line.p1() v = QPointF(u.y(), -u.x()) mag_u = mag2D(u) if abs(mag_u) != 0: if self._firstTimeNonzero: self._firstTimeNonzero = False label = self.label(-1) if label: label.setPos(self.pointCenter()) u /= mag_u v /= mag_u r = self.arrowHeadSize() if self._mono: line_end = line.p1() + u * r else: line_end = line.p1() if not self.isBezier(): path.lineTo(line_end) else: path.cubicTo(self._points[-2].pos(), self._points[-3].pos(), line_end) if self._mono: perp_end = 1.5 * r * v path.cubicTo(line.p1(), line.p1() + perp_end, line_end + perp_end) return path
def _pointWithinThreshold(x, y, curve, eps): """ See whether *(x, y)* is within *eps* of *curve*. """ path = QPainterPath() path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps) curvePath = QPainterPath() if curve[-1].segmentType == "curve": p1, p2, p3, p4 = curve curvePath.moveTo(p1.x, p1.y) curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y) curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y) else: first = curve[0] curvePath.moveTo(first.x, first.y) # PACK for fontTools pts = [] for pt in curve: pts.append((pt.x, pt.y)) # draw for pt1, pt2 in decomposeQuadraticSegment(pts[1:]): curvePath.quadTo(*pt1+pt2) for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))): curvePath.quadTo(*pt1+pt2) return path.intersects(curvePath)
def draw_connection_line(painter, x1, y1, x2, y2, h1, h2): # Account for list view headers. y1 += h1 y2 += h2 # Invisible output ports don't get a connecting dot. if y1 > h1: painter.drawLine(x1, y1, x1 + 4, y1) # Setup control points spline = QPolygon(4) cp = int((x2 - x1 - 8) * 0.4) spline.setPoints(x1 + 4, y1, x1 + 4 + cp, y1, x2 - 4 - cp, y2, x2 - 4, y2) # The connection line path = QPainterPath() path.moveTo(spline.at(0)) path.cubicTo(spline.at(1), spline.at(2), spline.at(3)) painter.strokePath(path, painter.pen()) # painter.drawLine(x1 + 4, y1, x2 - 4, y2) # Invisible input ports don't get a connecting dot. if y2 > h2: painter.drawLine(x2 - 4, y2, x2, y2)
def paintEvent(self, event): super(WinMinButton, self).paintEvent(event) if not self.show_foreground: return # 不显示前景 w = self._w h = self._h left = QPoint(self._l + w / 3, self._t + h / 2) right = QPoint(self._l + w * 2 / 3, self._t + h / 2) mid = QPoint(self._l + w / 2 + self.offset_pos.x(), self._t + h / 2 + self.offset_pos.y()) if self.click_ani_appearing or self.click_ani_disappearing: pro = self.click_ani_progress / 800.0 left.setX(left.x() - left.x() * pro) right.setX(right.x() + (w - right.x()) * pro) painter = QPainter(self) path = QPainterPath() path.moveTo(left) path.cubicTo(left, mid, right) painter.setPen(QPen(self.icon_color)) if left.y() != mid.y(): painter.setRenderHint(QPainter.Antialiasing, True) painter.drawPath(path)
def draw_connection_line(self, painter, x1, y1, x2, y2, h1, h2): # Account for list view headers. y1 += h1 y2 += h2 # Invisible output ports don't get a connecting dot. if y1 > h1: painter.drawLine(x1, y1, x1 + 4, y1) # Setup control points spline = QPolygon(4) cp = int((x2 - x1 - 8) * 0.4) spline.setPoints(x1 + 4, y1, x1 + 4 + cp, y1, x2 - 4 - cp, y2, x2 - 4, y2) # The connection line path = QPainterPath() path.moveTo(spline.at(0)) path.cubicTo(spline.at(1), spline.at(2), spline.at(3)) painter.strokePath(path, painter.pen()) # painter.drawLine(x1 + 4, y1, x2 - 4, y2) # Invisible input ports don't get a connecting dot. if y2 > h2: painter.drawLine(x2 - 4, y2, x2, y2)
def paint(self, painter, option, widget=None): """Draw a Bezier curve connecting selected Nodes""" qp = painter qp.setRenderHint(QPainter.HighQualityAntialiasing) from_point = self.start.get_pos() posn1 = self.handle1.scenePos() posn2 = self.handle2.scenePos() path = QPainterPath(from_point) if self.end_term: self.end_point = self.end_term.get_pos() # Draw path path.cubicTo(posn1, posn2, self.end_point) wire_pen = QPen(QColor('#aa00ff'), 2) wire_pen.setCosmetic(True) qp.setPen(wire_pen) qp.drawPath(path) if self.parent.vis: #if self.isSelected(): # Draw helper lines (https://gist.github.com/Alquimista/1274149) control_points = ((from_point.x(), from_point.y()), (posn1.x(), posn1.y()), (posn2.x(), posn2.y()), (self.end_point.x(), self.end_point.y())) old_point = control_points[0] helper_pen = QPen(Qt.darkGreen, 1, Qt.DashLine) for i, point in enumerate(control_points[1:]): i += 2 qp.setPen(helper_pen) qp.drawLine(old_point[0], old_point[1], point[0], point[1]) old_point = point
class Window(QDialog): def __init__(self): super().__init__() self.dialog = uic.loadUi("demoAnimation2.ui", self) # načtení formuláře self.show() self.path = QPainterPath() self.path.moveTo(30, 30) self.path.cubicTo(30, 30, 80, 180, 180, 170) self.labelPic.pos = QPointF(20, 20) def paintEvent(self, e): qp = QPainter() qp.begin(self) qp.drawPath(self.path) qp.end() def startAnimation(self): self.anim = QPropertyAnimation( self.labelPic, b"pos") # vytvoření objektu třídy QPropertyAnimation self.anim.setDuration(4000) # prodlevy při animaci self.anim.setStartValue(QPointF(20, 20)) positionValues = [n / 80 for n in range(0, 50)] for i in positionValues: self.anim.setKeyValueAt(i, self.path.pointAtPercent(i)) self.anim.setEndValue(QPointF(160, 150)) self.anim.start()
def drawBezierCurve(self, qp): path = QPainterPath() path.moveTo(30, 30) # 使用cubicTo()方法生成,分别需要三个点:起始点,控制点和终止点。 path.cubicTo(30, 30, 200, 350, 350, 30) # 绘制最后的图像。 qp.drawPath(path)
class MyForm(QDialog): def __init__(self): super().__init__() self.ui=Ui_Dialog() self.ui.setupUi(self) self.ui.pushButtonMoveCurve.clicked.connect(self.startAnimation) self.path = QPainterPath() self.path.moveTo(30, 30) self.path.cubicTo(30, 30, 80, 180, 180, 170) self.ui.labelpic.pos=QPointF(20,20) def paintEvent(self, e): qp = QPainter() qp.begin(self) qp.drawPath(self.path) qp.end() def startAnimation(self): self.anim = QPropertyAnimation(self.ui.labelpic, b'geometry') self.anim.setDuration(10000) self.anim.setStartValue(QPointF(20, 20)) positionValues = [n / 80 for n in range(0, 50)] for i in positionValues: self.anim.setKeyValueAt(i, self.path.pointAtPercent(i)) self.anim.setEndValue(QPointF(160, 150)) self.anim.start()
def drawBezierCurve(self, qp): path = QPainterPath() path.moveTo(30, 30) path.cubicTo(30, 30, 200, 350, 350, 30) qp.drawPath(path)
def _pointWithinThreshold(x, y, curve, eps): """ See whether *(x, y)* is within *eps* of *curve*. """ path = QPainterPath() path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps) curvePath = QPainterPath() if curve[-1].segmentType == "curve": p1, p2, p3, p4 = curve curvePath.moveTo(p1.x, p1.y) curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y) curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y) else: first = curve[0] curvePath.moveTo(first.x, first.y) # PACK for fontTools pts = [] for pt in curve: pts.append((pt.x, pt.y)) # draw for pt1, pt2 in decomposeQuadraticSegment(pts[1:]): curvePath.quadTo(*pt1 + pt2) for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))): curvePath.quadTo(*pt1 + pt2) return path.intersects(curvePath)
def updatePath(self): end_hook = self.endSocket() if end_hook is None: return self.prepareGeometryChange() end_pos = self.mapFromItem(end_hook, 0.0, 0.0) + end_hook.boundingRect().center() if self._curve: if not self._keyPoints: tangent_length = (abs(end_pos.x()) / 2.0) + (abs(end_pos.y()) / 4.0) tangent_length2 = tangent_length else: first_pos = self._keyPoints[0] tangent_length = (abs(first_pos.x()) / 2.0) + (abs(first_pos.y()) / 4.0) last_pos = self._keyPoints[-1] last_segment = end_pos - last_pos tangent_length2 = (abs(last_segment.x()) / 2.0) + (abs(last_segment.y()) / 4.0) spread = 60.0 / 180.0 * pi # Find connection index index, number_connections = self.startSocket().getIndexInfo(self) dev = (index - number_connections / 2.0 + 0.5) * min( spread, pi / (number_connections + 2)) tx = tangent_length * cos(dev) ty = tangent_length * sin(dev) start_tangent = QPointF(tx, ty) end_tangent = QPointF(end_pos.x() - tangent_length2, end_pos.y()) path = QPainterPath() path.cubicTo(start_tangent, end_tangent, end_pos) # Dot styles are used for relationships else: path = QPainterPath() path.lineTo(end_pos) stroke_width = self._pen.widthF() rect = path.boundingRect().adjusted(-stroke_width, -stroke_width, stroke_width, stroke_width) # draw widget center_widget = self._centerWidget if center_widget is not None: center = path.pointAtPercent(0.5) center_widget.onUpdated(center, text=str(self.index)) self._path = path self._rect = rect
def _get_canvas_path(self, points) : (P1, P2) = bezier_control_points(points) path = QPainterPath() path.moveTo(QPointF(*points[0])) for p1,p2,p3 in zip(P1, P2, points[1:]) : path.cubicTo(*starmap(QPointF,(p1,p2,p3))) path.lineTo(QPointF(self.shift[0],points[-1][1])) return path
def drawBezierCurve(self, qp): # 用QPainterPath路径创建贝塞尔曲线。使用cubicTo()方法生成,分别需要三个点:起始点,控制点和终止点 path = QPainterPath() path.moveTo(30, 30) path.cubicTo(30, 30, 200, 350, 350, 30) # drawPath()绘制最后的图像 qp.drawPath(path)
class MyDialog(QDialog): def __init__(self): super().__init__() self.ui = Ui_Dialog() self.ui.setupUi(self) self.pixmap = QPixmap() self.pixmap.load('game_map.png') self.item = QGraphicsPixmapItem(self.pixmap) self.scene = QGraphicsScene() self.scene.addItem(self.item) self.ui.graphicsView.setScene(self.scene) self.ui.pushButton.clicked.connect(self.startanimation) self.path = QPainterPath() self.path.moveTo(30,30) self.path.cubicTo(30,30,80,180,180,170) self.ui.label.pos = QPointF(20,20) self.pos1 = [0,0] self.pos2 = [0,0] def mousePressEvent(self, event): if event.buttons() & QtCore.Qt.LeftButton: self.pos1[0] = event.x() self.pos1[1] = event.y() def mouseReleaseEvent(self, event): self.pos2[0] = event.x() self.pos2[1] = event.y() self.update() def paintEvent(self, event): width = self.pos2[0] - self.pos1[0] height = self.pos2[1] - self.pos1[1] rect = QRect(self.pos1[0],self.pos1[1],width,height) qp = QPainter() qp.begin(self) pen = QPen(Qt.red,3) pen.setStyle(Qt.DotLine) qp.setPen(pen) qp.drawArc(rect,0,360*16) qp.end() # def paintEvent(self,e): # qp = QPainter() # qp.begin(self) # qp.drawPath(self.path) # qp.end() def startanimation(self): self.anim = QPropertyAnimation(self.ui.label, b'pos') self.anim.setDuration(4000) self.anim.setStartValue(QPointF(20,20)) pos = [n/80 for n in range(0,50)] for i in pos: self.anim.setKeyValueAt(i,self.path.pointAtPercent(i)) self.anim.setEndValue(QPointF(160,150)) self.anim.start()
def getLargerEdgePath(self): #Used to fill in the small areas on the edge #This makes it easier to select the edge yTranslation = 2 #Curve 1 beginPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() + yTranslation) curvePoint1 = QPointF(self.curvePoint1.x() + 4, self.curvePoint1.y() + yTranslation) curvePoint2 = QPointF(self.curvePoint2.x() + 4, self.curvePoint2.y() + yTranslation) endPoint = QPointF(self.endPoint.x(), self.endPoint.y() + yTranslation) path = QPainterPath(beginPoint) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) #Arrow arrowBeginPoint = QPointF(self.endPoint.x(), self.endPoint.y() + 4) path.lineTo(arrowBeginPoint) if self.endSide == 'right': path.lineTo(QPointF(self.endPoint.x() - 10, self.endPoint.y())) else: path.lineTo(QPointF(self.endPoint.x() + 10, self.endPoint.y())) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 4)) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 2)) #Curve 2 (back) endPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() - yTranslation) curvePoint2 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() - yTranslation) curvePoint1 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() - yTranslation) beginPoint = QPointF(self.endPoint.x(), self.endPoint.y() - yTranslation) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) if self.beginSide == 'right': path.lineTo( QPointF(self.beginPoint.x() - 10, self.beginPoint.y() - 2)) path.lineTo( QPointF(self.beginPoint.x() - 10, self.beginPoint.y() + 2)) else: path.lineTo( QPointF(self.beginPoint.x() + 10, self.beginPoint.y() - 2)) path.lineTo( QPointF(self.beginPoint.x() + 10, self.beginPoint.y() + 2)) path.lineTo(QPointF(self.beginPoint.x(), self.beginPoint.y() + 2)) return path
def drawBezierCurve(self, qp): # 用`QPainterPath`路径创建贝塞尔曲线。 # 使用`cubicTo()`方法生成,分别需要三个点:起始点,控制点和终止点。 path = QPainterPath() path.moveTo(20, 120) path.cubicTo(20, 120, 170, 400, 330, 120) # `drawPath()`绘制最后的图像。 qp.drawPath(path)
def drawBezierCurve(self, qp): path = QPainterPath() path.moveTo(30, 30) # The curve is created with cubicTo() method, # which takes three points: starting point, # control point, and ending point. path.cubicTo(30, 30, 200, 350, 350, 30) qp.drawPath(path)
def getEdgePath(self): yTranslation = 2 #Curve 1 beginPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() + yTranslation) curvePoint1 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() + yTranslation) curvePoint2 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() + yTranslation) endPoint = QPointF(self.endPoint.x(), self.endPoint.y() + yTranslation) path = QPainterPath(beginPoint) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) #Arrow arrowBeginPoint = QPointF(self.endPoint.x(), self.endPoint.y() + 4) path.lineTo(arrowBeginPoint) if self.endSide == 'right': path.lineTo(QPointF(self.endPoint.x() - 10, self.endPoint.y())) else: path.lineTo(QPointF(self.endPoint.x() + 10, self.endPoint.y())) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 4)) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 2)) #Curve 2 (back) endPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() - yTranslation) curvePoint2 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() - yTranslation) curvePoint1 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() - yTranslation) beginPoint = QPointF(self.endPoint.x(), self.endPoint.y() - yTranslation) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) if self.beginSide == 'right': path.lineTo( QPointF(self.beginPoint.x() - 10, self.beginPoint.y() - 2)) path.lineTo( QPointF(self.beginPoint.x() - 10, self.beginPoint.y() + 2)) else: path.lineTo( QPointF(self.beginPoint.x() + 10, self.beginPoint.y() - 2)) path.lineTo( QPointF(self.beginPoint.x() + 10, self.beginPoint.y() + 2)) path.lineTo(QPointF(self.beginPoint.x(), self.beginPoint.y() + 2)) return path
def updateShape(self): # Create the bezier curve path srcX, srcY = self.srcSocket.linkConnectionPos() dstX, dstY = self.dstSocket.linkConnectionPos() linkPath = QPainterPath() linkPath.setFillRule(Qt.WindingFill) linkPath.moveTo(srcX, srcY) linkPath.cubicTo(srcX + 100, srcY, dstX - 100, dstY, dstX, dstY) self.setPath(linkPath)
def drawBezierCurve(self, painter): """自定义绘制参数""" path = QPainterPath() path.moveTo(30, 30) # cubicTo: 启始点,控制点,终止点 path.cubicTo(30, 30, 200, 350, 350, 30) painter.drawPath(path)
def drawBezierCurve(self, qp): # create a Bézier curve with QPainterPath path. The curve is # created with cubicTo() method, which takes three # points: starting point, control point, and ending point. path = QPainterPath() path.moveTo(30, 30) path.cubicTo(30, 30, 200, 350, 350, 30) qp.drawPath(path)
def calc_path(self) -> QPainterPath: """Calculates the line path for the GraphicsEdge based on the line type. Returns: QPainterPath: The edge's line path object. Todo: * Make more readable. Get rid of s & d shit. * More elegant way to check the type of line? """ if self.__edge_type == EDGE_TYPE_DIRECT: path = QPainterPath(QPointF(self.pos_source.x, self.pos_source.y)) path.lineTo(self.pos_destination.x, self.pos_destination.y) return path elif self.__edge_type == EDGE_TYPE_BEZIER: s = self.pos_source d = self.pos_destination dist = (d.x - s.x) * 0.5 cpx_s = +dist cpx_d = -dist cpy_s = 0 cpy_d = 0 if self.edge.start_socket is not None: sspos = self.edge.start_socket.position if (s.x > d.x and sspos in (node_socket.RIGHT_TOP, node_socket.RIGHT_BOTTOM)) or ( s.x < d.x and sspos in (node_socket.LEFT_BOTTOM, node_socket.LEFT_TOP)): cpx_d *= -1 cpx_s *= -1 cpy_d = ((s.y - d.y) / math.fabs( (s.y - d.y) if (s.y - d.y) != 0 else 0.00001)) * EDGE_CP_ROUNDNESS cpy_s = ((d.y - s.y) / math.fabs( (d.y - s.y) if (d.y - s.y) != 0 else 0.00001)) * EDGE_CP_ROUNDNESS path = QPainterPath(QPointF(self.pos_source.x, self.pos_source.y)) path.cubicTo(s.x + cpx_s, s.y + cpy_s, d.x + cpx_d, d.y + cpy_d, self.pos_destination.x, self.pos_destination.y) return path else: logparams.logging.debug( f"Edge type is not correct: {self.__edge_type}") raise Exception return None
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', '') 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)
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() min_len = self._source.radius() + self._dest.radius( ) + self._source.pen().widthF() + self._dest.pen().widthF() if length > min_len: offset = QPointF( (line.dx() * (self._source.radius() + self._source.pen().widthF() + 1)) / length, (line.dy() * (self._source.radius() + self._source.pen().widthF() + 1)) / length) self.source_point = line.p1() + offset offset = QPointF( (line.dx() * (self._dest.radius() + self._dest.pen().widthF() + 1)) / length, (line.dy() * (self._dest.radius() + self._dest.pen().widthF() + 1)) / length) self.dest_point = line.p2() - offset else: self.source_point = self.dest_point = line.p1() path = QPainterPath() if self.sourceNode() == self.destNode(): # Draw self-loops self.__is_self_loop = True radius = self._source.radius() path.moveTo( self.source_point.x() - radius - 2 * self._source.pen().widthF(), self.source_point.y()) path.cubicTo( QPointF(self.source_point.x() - 4 * radius, self.source_point.y()), QPointF(self.source_point.x(), self.source_point.y() - 4 * radius), QPointF( self.dest_point.x(), self.dest_point.y() - radius - 2 * self._source.pen().widthF())) else: self.__is_self_loop = False path.moveTo(self.source_point) path.lineTo(self.dest_point) self.setPath(path)
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 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.green) else: painter.setPen(Qt.red)
def getPointCloseToCenter(self, distance): edgePath = QPainterPath(self.beginPoint) edgePath.cubicTo(self.curvePoint1, self.curvePoint2, self.endPoint) if edgePath.length() > 0: percent = (edgePath.length() / 2 + distance) / edgePath.length() else: percent = 0 #Snap to begin/end point when the edge is too small if percent < 0: percent = 0 elif percent > 1: percent = 1 return self.getPointOnEdge(percent)
def FillScene(aScene, aProcessGraphics): maxRow = 0 maxCol = 0 for graphic in aProcessGraphics: maxRow = max(maxRow, graphic.row) maxCol = max(maxCol, graphic.col) maxRow = maxRow + 1 maxCol = maxCol + 1 colWidth = 400 rowHeigth = 360 border = 50 sceneWidth = colWidth * maxCol + border * 2 sceneHeight = rowHeigth * maxRow + border * 2 aScene.setSceneRect(QRectF(0, 0, sceneWidth, sceneHeight)) aScene.clear() ## Set process positions for graphic in aProcessGraphics: x = 50 + sceneWidth - (graphic.col + 1) * colWidth y = 50 + graphic.row * rowHeigth graphic.setPos(QPointF(x, y)) aScene.addItem(graphic) ## Add lines for graphic in aProcessGraphics: for inp in graphic.inputs: for child in inp.children: controlOffset = 100 start = child.GetScenePos() control1 = start + QPointF(controlOffset, 0) end = inp.GetScenePos() control2 = end + QPointF(-controlOffset, 0) path = QPainterPath() path.moveTo(start) path.cubicTo(control1, control2, end) line = QGraphicsPathItem(path) line.setZValue(-1000) aScene.addItem(line)
def getLargerEdgePath(self): #Used to fill in the small areas on the edge #This makes it easier to select the edge yTranslation = 2 #Curve 1 beginPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() + yTranslation) curvePoint1 = QPointF(self.curvePoint1.x()+4, self.curvePoint1.y() + yTranslation) curvePoint2 = QPointF(self.curvePoint2.x()+4, self.curvePoint2.y() + yTranslation) endPoint = QPointF(self.endPoint.x(), self.endPoint.y() + yTranslation) path = QPainterPath(beginPoint) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) #Arrow arrowBeginPoint = QPointF(self.endPoint.x(), self.endPoint.y() + 4) path.lineTo(arrowBeginPoint) if self.endSide == 'right': path.lineTo(QPointF(self.endPoint.x() - 10, self.endPoint.y())) else: path.lineTo(QPointF(self.endPoint.x() + 10, self.endPoint.y())) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 4)) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 2)) #Curve 2 (back) endPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() - yTranslation) curvePoint2 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() - yTranslation) curvePoint1 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() - yTranslation) beginPoint = QPointF(self.endPoint.x(), self.endPoint.y() - yTranslation) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) if self.beginSide == 'right': path.lineTo(QPointF(self.beginPoint.x() - 10, self.beginPoint.y() - 2)) path.lineTo(QPointF(self.beginPoint.x() - 10, self.beginPoint.y() + 2)) else: path.lineTo(QPointF(self.beginPoint.x() + 10, self.beginPoint.y() - 2)) path.lineTo(QPointF(self.beginPoint.x() + 10, self.beginPoint.y() + 2)) path.lineTo(QPointF(self.beginPoint.x(), self.beginPoint.y() + 2)) return path
def paint(self, painter: QPainter): painter_path = QPainterPath() painter_path.moveTo(self._startX, self._startY) x1 = (7 * self._endX + self._startX) / 8 y1 = self._startY x2 = (self._endX + 7 * self._startX) / 8 y2 = self._endY painter_path.cubicTo(x1, y1, x2, y2, self._endX, self._endY) if self._startArrow: self.add_arrow(self._startX, self._startY, 'l' if self._startX <= self._endX else 'r',painter_path) if self._endArrow: self.add_arrow(self._endX, self._endY, 'r' if self._startX <= self._endX else 'l',painter_path) pen = QPen(self._color, self._curveWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) painter.setPen(pen) painter.setRenderHints(QPainter.Antialiasing, True) painter.drawPath(painter_path)
def getEdgePath(self): yTranslation = 2 #Curve 1 beginPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() + yTranslation) curvePoint1 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() + yTranslation) curvePoint2 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() + yTranslation) endPoint = QPointF(self.endPoint.x(), self.endPoint.y() + yTranslation) path = QPainterPath(beginPoint) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) #Arrow arrowBeginPoint = QPointF(self.endPoint.x(), self.endPoint.y() + 4) path.lineTo(arrowBeginPoint) if self.endSide == 'right': path.lineTo(QPointF(self.endPoint.x() - 10, self.endPoint.y())) else: path.lineTo(QPointF(self.endPoint.x() + 10, self.endPoint.y())) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 4)) path.lineTo(QPointF(self.endPoint.x(), self.endPoint.y() - 2)) #Curve 2 (back) endPoint = QPointF(self.beginPoint.x(), self.beginPoint.y() - yTranslation) curvePoint2 = QPointF(self.curvePoint1.x(), self.curvePoint1.y() - yTranslation) curvePoint1 = QPointF(self.curvePoint2.x(), self.curvePoint2.y() - yTranslation) beginPoint = QPointF(self.endPoint.x(), self.endPoint.y() - yTranslation) point1 = QPointF(curvePoint1.x(), curvePoint1.y()) point2 = QPointF(curvePoint2.x(), curvePoint2.y()) path.cubicTo(point1, point2, endPoint) if self.beginSide == 'right': path.lineTo(QPointF(self.beginPoint.x() - 10, self.beginPoint.y() - 2)) path.lineTo(QPointF(self.beginPoint.x() - 10, self.beginPoint.y() + 2)) else: path.lineTo(QPointF(self.beginPoint.x() + 10, self.beginPoint.y() - 2)) path.lineTo(QPointF(self.beginPoint.x() + 10, self.beginPoint.y() + 2)) path.lineTo(QPointF(self.beginPoint.x(), self.beginPoint.y() + 2)) return path
def paint(self, painter, option, widget): # Body. painter.setBrush(self.color) painter.drawEllipse(-10, -20, 20, 40) # Eyes. painter.setBrush(Qt.white) painter.drawEllipse(-10, -17, 8, 8) painter.drawEllipse(2, -17, 8, 8) # Nose. painter.setBrush(Qt.black) painter.drawEllipse(QRectF(-2, -22, 4, 4)) # Pupils. painter.drawEllipse(QRectF(-8.0 + self.mouseEyeDirection, -17, 4, 4)) painter.drawEllipse(QRectF(4.0 + self.mouseEyeDirection, -17, 4, 4)) # Ears. if self.scene().collidingItems(self): painter.setBrush(Qt.red) else: painter.setBrush(Qt.darkYellow) painter.drawEllipse(-17, -12, 16, 16) painter.drawEllipse(1, -12, 16, 16) # Tail. path = QPainterPath(QPointF(0, 20)) path.cubicTo(-5, 22, -5, 22, 0, 25) path.cubicTo(5, 27, 5, 32, 0, 30) path.cubicTo(-5, 32, -5, 42, 0, 35) painter.setBrush(Qt.NoBrush) painter.drawPath(path)
def update(self, pos=None): path = QPainterPath() if pos is not None: if self.ioend is None: startpos = self.iostart.pos() + self.iostart.parent.pos() endpos = pos elif self.iostart is None: startpos = pos endpos = self.ioend.pos() + self.ioend.parent.pos() else: startpos = self.iostart.pos() + self.iostart.parent.pos() endpos = self.ioend.pos() + self.ioend.parent.pos() controlpoint = QPointF(abs((endpos - startpos).x()) * 0.8, 0) path.moveTo(startpos) path.cubicTo(startpos + controlpoint, endpos - controlpoint, endpos) self.setPath(path)
def activateNeighbor(self, active_prexoveritem, shortcut=None): """To be called with whatever the active_prexoveritem is for the parts `active_base` Args: active_prexoveritem (TYPE): Description shortcut (None, optional): Description """ p1 = self._phos_item.scenePos() p2 = active_prexoveritem._phos_item.scenePos() scale = 3 delta1 = -BASE_WIDTH*scale if self.is_fwd else BASE_WIDTH*scale delta2 = BASE_WIDTH*scale if active_prexoveritem.is_fwd else -BASE_WIDTH*scale c1 = self.mapFromScene(QPointF(p1.x(), p1.y() + delta1)) c2 = self.mapFromScene(QPointF(p2.x(), p2.y() - delta2)) pp = QPainterPath() pp.moveTo(self._phos_item.pos()) pp.cubicTo(c1, c2, self._bond_item.mapFromScene(p2)) self._bond_item.setPath(pp) self._bond_item.show() alpha = 32 idx, active_idx = self.idx, active_prexoveritem.idx if self.is_fwd != active_prexoveritem.is_fwd: if idx == active_idx: alpha = 255 elif idx == active_idx + 1: alpha = 255 elif idx == active_idx - 1: alpha = 255 inactive_alpha = PROX_ALPHA if self.to_vh_id_num is not None else 0 self.setBrush(getBrushObj(self._color, alpha=inactive_alpha)) self.animate(self, 'brush_alpha', 500, inactive_alpha, alpha) self.animate(self._phos_item, 'rotation', 500, 0, -90) self.setLabel(text=shortcut, outline=True)
def paintEvent(self, event): rect = QRect(10, 20, 80, 60) path = QPainterPath() path.moveTo(20, 80) path.lineTo(20, 30) path.cubicTo(80, 0, 50, 50, 80, 80) startAngle = 30 * 16 arcLength = 120 * 16 painter = QPainter(self) painter.setPen(self.pen) painter.setBrush(self.brush) if self.antialiased: painter.setRenderHint(QPainter.Antialiasing) angle_step = 360 / self.n_states painter.save() painter.translate(self.dist_center.x(), self.dist_center.y()) #painter.drawRect(- self.dist_radius, - self.dist_radius, self.dist_radius *2,self.dist_radius*2) #painter.drawEllipse(QPoint(0, 0), self.dist_radius , self.dist_radius) painter.rotate(-180) #to start painting from the left side of the circle x = self.dist_radius * math.cos(0) y = self.dist_radius * math.sin(0) for h in range(self.n_states): rot = angle_step * h painter.save() painter.rotate(rot) painter.translate(x,y) if self.machine.getState(h).isActive(): painter.setBrush(self.greenGradientBrush) painter.drawEllipse(QPoint(0,0), self.state_radius, self.state_radius) #global position of transformed coordinates gx = painter.worldTransform().map(QPoint(0,0)).x() gy = painter.worldTransform().map(QPoint(0,0)).y() self.machine.getState(h).setPos(gx, gy) # text transformation painter.save() painter.rotate(180) painter.rotate(-rot) font = painter.font(); font.setPixelSize(self.state_radius*.4); painter.setFont(font); rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2) painter.drawText(rect, Qt.AlignCenter, self.machine.getState(h).getName()); painter.restore() #end text transformation painter.restore() painter.restore() #drawing transitions. painter.save() pptv = QTransform() pptv.translate(0, self.height()) pptv.rotate(-180, Qt.XAxis) painter.setTransform(pptv) s = self.machine.getStates() for j in s: t = j.getTransitions() for i in t: #get the points in the canvas init = QPoint(j.getPos()[0], j.getPos()[1]) end = QPoint(self.machine.getState(i.getStateEnd()).getPos()[0], self.machine.getState(i.getStateEnd()).getPos()[1]) # get the transformed ponts init2 = QPoint(painter.worldTransform().map(init)) end2 = QPoint(painter.worldTransform().map(end)) #get the angle between states centers angle = math.atan2(end2.y() - init2.y(), end2.x() - init2.x()) #get the coordinates of the starting point of the transition (it starts in the bound, not in the center) newX = self.state_radius * math.cos(angle) + init2.x() newY = self.state_radius * math.sin(angle) + init2.y() init2.setX(newX) init2.setY(newY) #same for the end of the transition angle2 = math.atan2(init2.y() - end2.y(), init2.x() - end2.x()) newX2 = self.state_radius * math.cos(angle2) + end2.x() newY2 = self.state_radius * math.sin(angle2) + end2.y() end2.setX(newX2) end2.setY(newY2) #painter.drawLine(init, end) painter.drawLine(init2, end2) init = QPoint(painter.worldTransform().map(init2)) end = QPoint(painter.worldTransform().map(end2)) i.setOrig(init.x(), init.y()) i.setDest(end.x(), end.y()) i.setAngle(angle) #painter.draw painter.restore() painter.setPen(QPen(QColor(Qt.gray), 3)) for i in machine.getStates(): for j in i.getTransitions(): i = QPoint(j.getOrig()[0], j.getOrig()[1]) o = QPoint(j.getDest()[0], j.getDest()[1]) painter.drawPolyline(i, o) painter.save() painter.setPen(QPen(QColor(Qt.gray), 2)) painter.translate(j.getDest()[0],j.getDest()[1]) painter.rotate(90 - j.getAngle()*180/math.pi) a = QPoint(0,0) b = QPoint(-5,10) c = QPoint(5,10) a1 = painter.worldTransform().map(a) b1 = painter.worldTransform().map(b) c1 = painter.worldTransform().map(c) pointer = QPolygon([a,b,c]) painter.drawPolygon(pointer) painter.restore() painter.save() if j.isActive(): t = self.machine.getTransition(self.t_active) init = QPoint(t.getOrig()[0], t.getOrig()[1]) end = QPoint(t.getDest()[0], t.getDest()[1]) painter.setPen(QPen(QColor(Qt.green), 3)) painter.drawPolyline(init, end) painter.setPen(QPen(QColor(Qt.gray), 3)) painter.drawPolyline(self.poly(self.pts)) painter.setBrush(QBrush(QColor(255, 0, 0))) painter.setPen(QPen(QColor(Qt.red), 2)) pointer = QPolygon([a1,b1,c1]) painter.drawPolygon(pointer) painter.setBrush(QBrush(QColor(255, 0, 0))) painter.setPen(QPen(QColor(Qt.black), 1)) painter.restore() #Ball that follows the line #for x, y in self.pts: #painter.drawEllipse(QRectF(x - 4, y - 4, 8, 8)) painter.save() pptv = QTransform() painter.setPen(QPen(QColor(Qt.black), 3)) middleX = (j.getOrig()[0] + j.getDest()[0]) /2 middleY = (j.getOrig()[1] + j.getDest()[1]) /2 pptv.translate(middleX, middleY) #pptv.rotate(-j.getAngle()*180/math.pi) painter.setTransform(pptv) font = painter.font(); font.setPixelSize(self.state_radius*.3); painter.setFont(font); rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2) name = str(j.getId())+ '. ' + j.getName() painter.drawText(rect, Qt.AlignCenter, name) painter.restore() painter.setPen(self.palette().dark().color()) painter.setBrush(Qt.NoBrush) painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1))
def __init__(self): super(Window, self).__init__() rectPath = QPainterPath() rectPath.moveTo(20.0, 30.0) rectPath.lineTo(80.0, 30.0) rectPath.lineTo(80.0, 70.0) rectPath.lineTo(20.0, 70.0) rectPath.closeSubpath() roundRectPath = QPainterPath() roundRectPath.moveTo(80.0, 35.0) roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0) roundRectPath.lineTo(25.0, 30.0) roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0) roundRectPath.lineTo(20.0, 65.0) roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0) roundRectPath.lineTo(75.0, 70.0) roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0) roundRectPath.closeSubpath() ellipsePath = QPainterPath() ellipsePath.moveTo(80.0, 50.0) ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0) piePath = QPainterPath() piePath.moveTo(50.0, 50.0) piePath.lineTo(65.0, 32.6795) piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0) piePath.closeSubpath() polygonPath = QPainterPath() polygonPath.moveTo(10.0, 80.0) polygonPath.lineTo(20.0, 10.0) polygonPath.lineTo(80.0, 30.0) polygonPath.lineTo(90.0, 70.0) polygonPath.closeSubpath() groupPath = QPainterPath() groupPath.moveTo(60.0, 40.0) groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0) groupPath.moveTo(40.0, 40.0) groupPath.lineTo(40.0, 80.0) groupPath.lineTo(80.0, 80.0) groupPath.lineTo(80.0, 40.0) groupPath.closeSubpath() textPath = QPainterPath() timesFont = QFont('Times', 50) timesFont.setStyleStrategy(QFont.ForceOutline) textPath.addText(10, 70, timesFont, "Qt") bezierPath = QPainterPath() bezierPath.moveTo(20, 30) bezierPath.cubicTo(80, 0, 50, 50, 80, 80) starPath = QPainterPath() starPath.moveTo(90, 50) for i in range(1, 5): starPath.lineTo(50 + 40 * cos(0.8 * i * pi), 50 + 40 * sin(0.8 * i * pi)) starPath.closeSubpath() self.renderAreas = [RenderArea(rectPath), RenderArea(roundRectPath), RenderArea(ellipsePath), RenderArea(piePath), RenderArea(polygonPath), RenderArea(groupPath), RenderArea(textPath), RenderArea(bezierPath), RenderArea(starPath)] assert len(self.renderAreas) == 9 self.fillRuleComboBox = QComboBox() self.fillRuleComboBox.addItem("Odd Even", Qt.OddEvenFill) self.fillRuleComboBox.addItem("Winding", Qt.WindingFill) fillRuleLabel = QLabel("Fill &Rule:") fillRuleLabel.setBuddy(self.fillRuleComboBox) self.fillColor1ComboBox = QComboBox() self.populateWithColors(self.fillColor1ComboBox) self.fillColor1ComboBox.setCurrentIndex( self.fillColor1ComboBox.findText("mediumslateblue")) self.fillColor2ComboBox = QComboBox() self.populateWithColors(self.fillColor2ComboBox) self.fillColor2ComboBox.setCurrentIndex( self.fillColor2ComboBox.findText("cornsilk")) fillGradientLabel = QLabel("&Fill Gradient:") fillGradientLabel.setBuddy(self.fillColor1ComboBox) fillToLabel = QLabel("to") fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) penWidthLabel = QLabel("&Pen Width:") penWidthLabel.setBuddy(self.penWidthSpinBox) self.penColorComboBox = QComboBox() self.populateWithColors(self.penColorComboBox) self.penColorComboBox.setCurrentIndex( self.penColorComboBox.findText('darkslateblue')) penColorLabel = QLabel("Pen &Color:") penColorLabel.setBuddy(self.penColorComboBox) self.rotationAngleSpinBox = QSpinBox() self.rotationAngleSpinBox.setRange(0, 359) self.rotationAngleSpinBox.setWrapping(True) self.rotationAngleSpinBox.setSuffix(u'\N{DEGREE SIGN}') rotationAngleLabel = QLabel("&Rotation Angle:") rotationAngleLabel.setBuddy(self.rotationAngleSpinBox) self.fillRuleComboBox.activated.connect(self.fillRuleChanged) self.fillColor1ComboBox.activated.connect(self.fillGradientChanged) self.fillColor2ComboBox.activated.connect(self.fillGradientChanged) self.penColorComboBox.activated.connect(self.penColorChanged) for i in range(Window.NumRenderAreas): self.penWidthSpinBox.valueChanged.connect(self.renderAreas[i].setPenWidth) self.rotationAngleSpinBox.valueChanged.connect(self.renderAreas[i].setRotationAngle) topLayout = QGridLayout() for i in range(Window.NumRenderAreas): topLayout.addWidget(self.renderAreas[i], i / 3, i % 3) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 4) mainLayout.addWidget(fillRuleLabel, 1, 0) mainLayout.addWidget(self.fillRuleComboBox, 1, 1, 1, 3) mainLayout.addWidget(fillGradientLabel, 2, 0) mainLayout.addWidget(self.fillColor1ComboBox, 2, 1) mainLayout.addWidget(fillToLabel, 2, 2) mainLayout.addWidget(self.fillColor2ComboBox, 2, 3) mainLayout.addWidget(penWidthLabel, 3, 0) mainLayout.addWidget(self.penWidthSpinBox, 3, 1, 1, 3) mainLayout.addWidget(penColorLabel, 4, 0) mainLayout.addWidget(self.penColorComboBox, 4, 1, 1, 3) mainLayout.addWidget(rotationAngleLabel, 5, 0) mainLayout.addWidget(self.rotationAngleSpinBox, 5, 1, 1, 3) self.setLayout(mainLayout) self.fillRuleChanged() self.fillGradientChanged() self.penColorChanged() self.penWidthSpinBox.setValue(2) self.setWindowTitle("Painter Paths")
def getPointOnEdge(self, t): edgePath = QPainterPath(self.beginPoint) edgePath.cubicTo(self.curvePoint1, self.curvePoint2, self.endPoint) return QPointF(edgePath.pointAtPercent(t))
def paintEvent(self, event): option = QStyleOption() option.initFrom(self) contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations if self.graphStyle == self.BarStyle: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit)) else: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1) max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled))) if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0: graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight) else: graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight) if self.graphStyle == self.BarStyle: height_scaling = float(contents_rect.height()) / graph_height else: height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height painter = QStylePainter(self) painter.drawPrimitive(QStyle.PE_Widget, option) painter.setClipRect(contents_rect) painter.save() painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1) painter.scale(-1, -1) painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle) for graph in (graph for graph in self.graphs if graph.enabled and graph.data): if self.boundary is not None and 0 < self.boundary < graph_height: boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary) pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) pen_color.setColorAt(0, graph.color) pen_color.setColorAt(1, graph.over_boundary_color) brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency)) brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency)) else: pen_color = graph.color brush_color = self.color_with_alpha(graph.color, self.fillTransparency) dataset = islice(reversed(graph.data), graph_width) if self.graphStyle == self.BarStyle: lines = [QLineF(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)] painter.setPen(QPen(pen_color, self.lineThickness)) painter.drawLines(lines) else: painter.translate(0, +self.lineThickness/2 - 1) if self.smoothEnvelope and self.smoothFactor > 0: min_value = 0 max_value = graph_height * height_scaling cx_offset = self.horizontalPixelsPerUnit / 3.0 smoothness = self.smoothFactor last_values = deque(3*[next(dataset) * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous envelope = QPainterPath() envelope.moveTo(0, last_values[0]) for x, y in enumerate(dataset, 1): x = x * self.horizontalPixelsPerUnit y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness last_values.appendleft(y) c1x = x - cx_offset * 2 c2x = x - cx_offset c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value envelope.cubicTo(c1x, c1y, c2x, c2y, x, y) else: envelope = QPainterPath() envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)])) if self.fillEnvelope or graph.fill_envelope: first_element = envelope.elementAt(0) last_element = envelope.elementAt(envelope.elementCount() - 1) fill_path = QPainterPath() fill_path.moveTo(last_element.x, last_element.y) fill_path.lineTo(last_element.x + 1, last_element.y) fill_path.lineTo(last_element.x + 1, -self.lineThickness) fill_path.lineTo(-self.lineThickness, -self.lineThickness) fill_path.lineTo(-self.lineThickness, first_element.y) fill_path.connectPath(envelope) painter.fillPath(fill_path, brush_color) painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin)) painter.translate(0, -self.lineThickness/2 + 1) if self.boundary is not None and self.boundaryColor: painter.setRenderHint(QStylePainter.Antialiasing, False) painter.setPen(QPen(self.boundaryColor, 1.0)) painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling) painter.restore() # queue the 'updated' signal to be emitted after returning to the main loop QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)