def __get_bezier_middle(self, bezier: QPainterPath) -> QPointF: """ Get the point in the middle of a bezier curve. """ percent_middle = bezier.percentAtLength( bezier.length() / 2) return bezier.pointAtPercent(percent_middle)
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()
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()
class RoundAnimation(QPropertyAnimation): def __init__(self, target, prop, parent=None): super(RoundAnimation, self).__init__(target, prop, parent) def updateCurrentTime(self, currentTime): self.path = QPainterPath() if self.path.isEmpty(): end = self.endValue() start = self.startValue() self.path.addEllipse(QRectF(start, end)) duration = self.duration() if duration == 0: progress = 1.0 else: progress = (((currentTime - 1) % duration) + 1) / float(duration) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.path.pointAtPercent(easedProgress) self.updateCurrentValue(pt)
def set_shape(self, width, height): ''' Define the symbol shape ''' circ = min(width, height) path = QPainterPath() path.addEllipse(0, 0, circ, circ) point1 = path.pointAtPercent(0.625) point2 = path.pointAtPercent(0.125) point3 = path.pointAtPercent(0.875) point4 = path.pointAtPercent(0.375) path.moveTo(point1) path.lineTo(point2) path.moveTo(point3) path.lineTo(point4) self.setPath(path) # call Join superclass, otherwise symbol will take Join shape super(Join, self).set_shape(circ, circ)
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
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()
class Animation(QPropertyAnimation): ''' 动画类 ''' def __init__(self, target, prop): ''' target, prop这个两个参数分别对应:动画的产生对象和setter ''' super(Animation, self).__init__(target, prop) def updateCurrentTime(self, currentTime): ''' currentTime(此属性保存动画的当前时间和进度)总是在变化的。 每次动画的currentTime更改时,都会调用updateCurrentTime()函数 ''' self.m_path = QPainterPath() if self.m_path.isEmpty(): end = self.endValue() start = self.startValue() # endValue()、startValue()分别表示动画的结束值和起始值 self.m_path.addEllipse(QRectF(start, end)) # 在指定的boundingRectangle内创建一个椭圆,这里是QRectF(start, end),并将其作为封闭的子路径添加到painter路径中。 dura = self.duration() progress = (((currentTime - 1) % dura) + 1) / float(dura) # duration()此属性保存动画的持续时间(以毫秒为单位)。 默认持续时间为250毫秒。progress则描绘了当前的完成比率。 easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 # 返回进度缓和曲线的有效进度。 进度必须介于0和1之间,而返回的有效进度可能超出这些范围。大于1就减1,小于0就加1。 pt = self.m_path.pointAtPercent(easedProgress) # 返回当前路径的百分比easedProgress处的点。 # 参数easedProgress必须介于0和1之间。当存在曲线时,百分比参数被映射到贝塞尔方程的t参数。 self.updateCurrentValue(pt) # 每次动画的当前值更改时,都会调用updateCurrentValue()。pt参数是新的当前值。没有这个函数动画动不了。 self.valueChanged.emit(pt) def startAnimation(self, startx, starty, endx, endy, duration): ''' setStartValue()、setEndValue()分别表示设置动画的起止位置,setDuration()设置动画的运行时间。 ''' self.setStartValue(QPointF(startx, starty)) self.setEndValue(QPointF(endx, endy)) self.setDuration(duration) self.setLoopCount(-1) # 值为-1时,动画将永远循环直至停止 self.start()
class _MoveAnimation(QPropertyAnimation): '''move animation''' MOVE1 = 1 MOVE2 = 2 MOVE3 = 3 def __init__(self, target, parent, easing = QEasingCurve.Custom): super(_MoveAnimation, self).__init__(target, b"pos") self.parent = parent self.easing = easing if easing != -1: self.setEasingCurve(easing) self.m_path = QPainterPath() def setMoveType(self, _type): self._type = _type def updateCurrentTime(self, currentTime): if self.m_path.isEmpty(): # end = self.endValue() start = self.startValue() if self._type == self.MOVE1: end = QPoint(self.parent.width() / 4.0, 0) elif self._type == self.MOVE2: end = QPoint((self.parent.width() / 4.0) * 3.0, 0) if not start: start = QPoint(self.parent.width() / 4.0, 0) # 第二个移动没有设置开始坐标,这里以第一个移动结束为开始 elif self._type == self.MOVE3: if not start: start = QPoint((self.parent.width() / 4.0) * 3.0, 0) # 第三个移动没有设置开始坐标,这里以第二个移动结束为开始 end = QPoint(self.parent.width(), 0) self.m_path.moveTo(start) self.m_path.addEllipse(QRectF(start, end)) dura = self.duration() if dura == 0: progress = 1.0 else: progress = (((currentTime - 1) % dura) + 1) / float(dura) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.m_path.pointAtPercent(easedProgress) self.updateCurrentValue(pt) self.valueChanged.emit(pt) super(_MoveAnimation, self).updateCurrentTime(currentTime)
class _MoveAnimation(QPropertyAnimation): '''move animation''' MOVE1 = 1 MOVE2 = 2 MOVE3 = 3 def __init__(self, target, parent, easing=QEasingCurve.Custom): super(_MoveAnimation, self).__init__(target, b"pos") self.parent = parent self.easing = easing if easing != -1: self.setEasingCurve(easing) self.m_path = QPainterPath() def setMoveType(self, _type): self._type = _type def updateCurrentTime(self, currentTime): if self.m_path.isEmpty(): # end = self.endValue() start = self.startValue() if self._type == self.MOVE1: end = QPoint(self.parent.width() / 4.0, 0) elif self._type == self.MOVE2: end = QPoint((self.parent.width() / 4.0) * 3.0, 0) if not start: start = QPoint(self.parent.width() / 4.0, 0) # 第二个移动没有设置开始坐标,这里以第一个移动结束为开始 elif self._type == self.MOVE3: if not start: start = QPoint((self.parent.width() / 4.0) * 3.0, 0) # 第三个移动没有设置开始坐标,这里以第二个移动结束为开始 end = QPoint(self.parent.width(), 0) self.m_path.moveTo(start) self.m_path.addEllipse(QRectF(start, end)) dura = self.duration() if dura == 0: progress = 1.0 else: progress = (((currentTime - 1) % dura) + 1) / float(dura) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.m_path.pointAtPercent(easedProgress) self.updateCurrentValue(pt) self.valueChanged.emit(pt) super(_MoveAnimation, self).updateCurrentTime(currentTime)
def reshape(self): ''' Update the connection or arrow shape ''' shape = QPainterPath() shape.moveTo(self.start_point) for point in self.middle_points: shape.lineTo(point) shape.lineTo(self.end_point) # If required draw an arrow head (e.g. in SDL NEXTSTATE and JOIN) if self.child.arrow_head: self.draw_arrow_head(shape, origin='head', kind=self.child.arrow_head) if self.child.arrow_tail: shape.moveTo(shape.pointAtPercent(0)) self.draw_arrow_head(shape, origin='tail', kind=self.child.arrow_head) self.setPath(shape)
class Example(QWidget): def __init__(self): super().__init__() self.initView() self.initAnimation() def initView(self): self.path = QPainterPath() self.path.moveTo(30, 30) self.path.cubicTo(30, 30, 200, 350, 350, 30) self.ball = Ball(self) self.ball.pos = QPointF(30, 30) self.setWindowTitle("Animation along curve") self.setGeometry(300, 300, 400, 300) self.show() def paintEvent(self, e): qp = QPainter() qp.begin(self) qp.setRenderHint(QPainter.Antialiasing) qp.drawPath(self.path) qp.end() def initAnimation(self): self.anim = QPropertyAnimation(self.ball, b'pos') self.anim.setDuration(7000) self.anim.setStartValue(QPointF(30, 30)) vals = [p/100 for p in range(0, 101)] for i in vals: self.anim.setKeyValueAt(i, self.path.pointAtPercent(i)) self.anim.setEndValue(QPointF(350, 30)) self.anim.start()
class _MpcbAnimation(QPropertyAnimation): def __init__(self, parent, target, index, easing = QEasingCurve.InQuad): super(_MpcbAnimation, self).__init__(target, b"pos") self.parent = parent self.m_pathType = 1 self.easing = easing self.createAnimation(target, index) def createAnimation(self, target, index): '''创建动画''' self.m_path = QPainterPath() if self.easing != -1: self.setEasingCurve(self.easing) self.setStartValue(QPointF(0, 0)) self.setEndValue(QPointF(90, 90)) self.setDuration(2000) self.setLoopCount(-1) def updateCurrentTime(self, currentTime): if self.m_pathType: if self.m_path.isEmpty(): end = self.endValue() start = self.startValue() self.m_path.moveTo(start) self.m_path.addEllipse(QRectF(start, end)) dura = self.duration() if dura == 0: progress = 1.0 else: progress = (((currentTime - 1) % dura) + 1) / float(dura) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.m_path.pointAtPercent(easedProgress) self.updateCurrentValue(pt) self.valueChanged.emit(pt) else: super(_MpcbAnimation, self).updateCurrentTime(currentTime)
def _draw(self, painter: QPainter, width: int, height: int): self.x = self.flower_center_x(width) * smoothen_curve( self.get_age_coefficient()) self.y = self.flower_center_y(height) * smoothen_curve( self.get_age_coefficient()) painter.setPen( QPen(Color.green, self.stem_width * smoothen_curve(self.get_age_coefficient()))) # draw the stem path = QPainterPath() path.quadTo(0, self.y * 0.6, self.x, self.y) painter.drawPath(path) # draw the leaves for position, coefficient, rotation in self.leafs: painter.save() # find the point on the stem and rotate the leaf accordingly painter.translate(path.pointAtPercent(position)) painter.rotate(degrees(rotation)) # rotate according to where the flower is leaning towards if self.y != 0: painter.rotate(-degrees(sin(self.x / self.y))) # make it so both leaves are facing the same direction if rotation < 0: painter.scale(-1, 1) painter.setBrush(QBrush(Color.green)) painter.setPen(QPen(0)) # draw the leaf leaf = QPainterPath() leaf.setFillRule(Qt.WindingFill) ls = self.leaf_size(width) * smoothen_curve( self.get_age_coefficient())**2 * coefficient leaf.quadTo(0.4 * ls, 0.5 * ls, 0, ls) leaf.cubicTo(0, 0.5 * ls, -0.4 * ls, 0.4 * ls, 0, 0) painter.drawPath(leaf) painter.restore()
class _MpcbAnimation(QPropertyAnimation): def __init__(self, parent, target, index, easing=QEasingCurve.InQuad): super(_MpcbAnimation, self).__init__(target, b"pos") self.parent = parent self.m_pathType = 1 self.easing = easing self.createAnimation(target, index) def createAnimation(self, target, index): '''创建动画''' self.m_path = QPainterPath() if self.easing != -1: self.setEasingCurve(self.easing) self.setStartValue(QPointF(0, 0)) self.setEndValue(QPointF(90, 90)) self.setDuration(2000) self.setLoopCount(-1) def updateCurrentTime(self, currentTime): if self.m_pathType: if self.m_path.isEmpty(): end = self.endValue() start = self.startValue() self.m_path.moveTo(start) self.m_path.addEllipse(QRectF(start, end)) dura = self.duration() if dura == 0: progress = 1.0 else: progress = (((currentTime - 1) % dura) + 1) / float(dura) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.m_path.pointAtPercent(easedProgress) self.updateCurrentValue(pt) self.valueChanged.emit(pt) else: super(_MpcbAnimation, self).updateCurrentTime(currentTime)
def goOn(self): self.anim = QPropertyAnimation(self.mascot, b"pos") self.mascotFlip.hide() self.mascotGif.start() self.mascot.show() path = QPainterPath() path.moveTo(-70, 410) for i in range(self.step): path.quadTo( QPointF( self.xRange / self.step * i - 70 + (self.xRange / self.step / 2), 410), QPointF((self.xRange / self.step) * i - 70 + (self.xRange / self.step), 430)) vals = [p / 100 for p in range(0, 101)] self.anim.setDuration(self.duration) for i in vals: self.anim.setKeyValueAt(i, path.pointAtPercent(i)) self.anim.start() self.anim.finished.connect(self.goFlip)
class Animation(QPropertyAnimation): LinearPath, CirclePath = range(2) def __init__(self, target, prop): super(Animation, self).__init__(target, prop) self.setPathType(Animation.LinearPath) def setPathType(self, pathType): self.m_pathType = pathType self.m_path = QPainterPath() def updateCurrentTime(self, currentTime): if self.m_pathType == Animation.CirclePath: if self.m_path.isEmpty(): end = self.endValue() start = self.startValue() self.m_path.moveTo(start) self.m_path.addEllipse(QRectF(start, end)) dura = self.duration() if dura == 0: progress = 1.0 else: progress = (((currentTime - 1) % dura) + 1) / float(dura) easedProgress = self.easingCurve().valueForProgress(progress) if easedProgress > 1.0: easedProgress -= 1.0 elif easedProgress < 0: easedProgress += 1.0 pt = self.m_path.pointAtPercent(easedProgress) self.updateCurrentValue(pt) self.valueChanged.emit(pt) else: super(Animation, self).updateCurrentTime(currentTime)
class NodeAnchorItem(GraphicsPathObject): """ The left/right widget input/output anchors. """ def __init__(self, parent, *args): self.__boundingRect = None GraphicsPathObject.__init__(self, parent, *args) self.setAcceptHoverEvents(True) self.setPen(QPen(Qt.NoPen)) self.normalBrush = QBrush(QColor("#CDD5D9")) self.connectedBrush = QBrush(QColor("#9CACB4")) self.setBrush(self.normalBrush) self.shadow = QGraphicsDropShadowEffect( blurRadius=10, color=QColor(SHADOW_COLOR), offset=QPointF(0, 0) ) self.setGraphicsEffect(self.shadow) self.shadow.setEnabled(False) # Does this item have any anchored links. self.anchored = False if isinstance(parent, NodeItem): self.__parentNodeItem = parent else: self.__parentNodeItem = None self.__anchorPath = QPainterPath() self.__points = [] self.__pointPositions = [] self.__fullStroke = None self.__dottedStroke = None self.__shape = None self.prepareGeometryChange() self.__boundingRect = None def parentNodeItem(self): """ Return a parent :class:`NodeItem` or ``None`` if this anchor's parent is not a :class:`NodeItem` instance. """ return self.__parentNodeItem 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 anchorPath(self): """ Return the anchor path (:class:`QPainterPath`). This is a curve on which the anchor points lie. """ return self.__anchorPath def setAnchored(self, anchored): """ Set the items anchored state. When ``False`` the item draws it self with a dotted stroke. """ self.anchored = anchored if anchored: self.setPath(self.__fullStroke) self.setBrush(self.connectedBrush) else: self.setPath(self.__dottedStroke) self.setBrush(self.normalBrush) def setConnectionHint(self, hint=None): """ Set the connection hint. This can be used to indicate if a connection can be made or not. """ raise NotImplementedError def count(self): """ Return the number of anchor points. """ return len(self.__points) def addAnchor(self, anchor, position=0.5): """ Add a new :class:`AnchorPoint` to this item and return it's index. The `position` specifies where along the `anchorPath` is the new point inserted. """ return self.insertAnchor(self.count(), anchor, position) def insertAnchor(self, index, anchor, position=0.5): """ Insert a new :class:`AnchorPoint` at `index`. See also -------- NodeAnchorItem.addAnchor """ if anchor in self.__points: raise ValueError("%s already added." % anchor) self.__points.insert(index, anchor) self.__pointPositions.insert(index, position) anchor.setParentItem(self) anchor.setPos(self.__anchorPath.pointAtPercent(position)) anchor.destroyed.connect(self.__onAnchorDestroyed) self.__updatePositions() self.setAnchored(bool(self.__points)) return index def removeAnchor(self, anchor): """ Remove and delete the anchor point. """ anchor = self.takeAnchor(anchor) anchor.hide() anchor.setParentItem(None) anchor.deleteLater() def takeAnchor(self, anchor): """ Remove the anchor but don't delete it. """ index = self.__points.index(anchor) del self.__points[index] del self.__pointPositions[index] anchor.destroyed.disconnect(self.__onAnchorDestroyed) self.__updatePositions() self.setAnchored(bool(self.__points)) return anchor def __onAnchorDestroyed(self, anchor): try: index = self.__points.index(anchor) except ValueError: return del self.__points[index] del self.__pointPositions[index] def anchorPoints(self): """ Return a list of anchor points. """ return list(self.__points) def anchorPoint(self, index): """ Return the anchor point at `index`. """ return self.__points[index] def setAnchorPositions(self, positions): """ Set the anchor positions in percentages (0..1) along the path curve. """ if self.__pointPositions != positions: self.__pointPositions = list(positions) self.__updatePositions() def anchorPositions(self): """ Return the positions of anchor points as a list of floats where each float is between 0 and 1 and specifies where along the anchor path does the point lie (0 is at start 1 is at the end). """ return list(self.__pointPositions) def shape(self): if self.__shape is not None: return self.__shape else: return GraphicsPathObject.shape(self) def boundingRect(self): if self.__boundingRect is None: self.__boundingRect = super(NodeAnchorItem, self).boundingRect() \ .adjusted(-5, -5, 5, 5) return self.__boundingRect def hoverEnterEvent(self, event): self.prepareGeometryChange() self.__boundingRect = None self.shadow.setEnabled(True) return GraphicsPathObject.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): self.prepareGeometryChange() self.__boundingRect = None self.shadow.setEnabled(False) return GraphicsPathObject.hoverLeaveEvent(self, event) def __updatePositions(self): """Update anchor points positions. """ self.prepareGeometryChange() self.__boundingRect = None for point, t in zip(self.__points, self.__pointPositions): pos = self.__anchorPath.pointAtPercent(t) point.setPos(pos)
def paintEvent(self, event): painter = QPainter(self) event.accept() painter.save() painter.setRenderHint(QPainter.Antialiasing, True) if self.fLabel: if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: painter.setPen(self.fLabelGradientColor2) painter.setBrush(self.fLabelGradient) painter.drawRect(self.fLabelGradientRect) painter.setFont(self.fLabelFont) painter.setPen( self.fLabelGradientColorT[0 if self.isEnabled() else 1]) painter.drawText(self.fLabelPos, self.fLabel) if self.isEnabled(): normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum) curLayer = int((self.fImageLayersCount - 1) * normValue) if self.fImageOrientation == self.HORIZONTAL: xpos = self.fImageBaseSize * curLayer ypos = 0.0 else: xpos = 0.0 ypos = self.fImageBaseSize * curLayer source = QRectF(xpos, ypos, self.fImageBaseSize, self.fImageBaseSize) if isinstance(self.fImage, QPixmap): target = QRectF(0.0, 0.0, self.fImageBaseSize, self.fImageBaseSize) painter.drawPixmap(target, self.fImage, source) else: self.fImage.renderer().render(painter, source) # Custom knobs (Dry/Wet and Volume) if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL): # knob color colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep * 6) colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep * 6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) #painter.drawRect(ballRect) tmpValue = (0.375 + 0.75 * normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 218 * 16 spanAngle = -255 * 16 * normValue if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_WET: painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 0)) painter.drawEllipse( QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) gradient = QConicalGradient(15.5, 15.5, -45) gradient.setColorAt(0.0, colorBlue) gradient.setColorAt(0.125, colorBlue) gradient.setColorAt(0.625, colorGreen) gradient.setColorAt(0.75, colorGreen) gradient.setColorAt(0.76, colorGreen) gradient.setColorAt(1.0, colorGreen) painter.setBrush(gradient) painter.setPen(QPen(gradient, 3)) else: painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 0)) painter.drawEllipse( QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 3)) painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (L and R) elif self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R): # knob color color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep * 6) # draw small circle ballRect = QRectF(7.0, 8.0, 11.0, 12.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) #painter.drawRect(ballRect) tmpValue = (0.375 + 0.75 * normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse( QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0)) # draw arc if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L: startAngle = 218 * 16 spanAngle = -255 * 16 * normValue else: startAngle = 322.0 * 16 spanAngle = 255.0 * 16 * (1.0 - normValue) painter.setPen(QPen(color, 2.5)) painter.drawArc(3.5, 3.5, 22.0, 22.0, startAngle, spanAngle) # Custom knobs (Color) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR: # knob color color = self.fCustomPaintColor.lighter(100 + self.fHoverStep * 6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) tmpValue = (0.375 + 0.75 * normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 218 * 16 spanAngle = -255 * 16 * normValue painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse( QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(color) painter.setPen(QPen(color, 3)) painter.drawArc(4.0, 4.8, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (Zita) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA: a = normValue * pi * 1.5 - 2.35 r = 10.0 x = 10.5 y = 10.5 x += r * sin(a) y -= r * cos(a) painter.setBrush(Qt.black) painter.setPen(QPen(Qt.black, 2)) painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y)) # Custom knobs else: painter.restore() return if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX: self.fHoverStep += 1 if self.fIsHovered else -1 QTimer.singleShot(20, self.update) else: # isEnabled() target = QRectF(0.0, 0.0, self.fImageBaseSize, self.fImageBaseSize) if isinstance(self.fImage, QPixmap): painter.drawPixmap(target, self.fImage, target) else: self.fImage.renderer().render(painter, target) painter.restore()
def paintEvent(self, event): painter = QPainter(self) event.accept() painter.save() painter.setRenderHint(QPainter.Antialiasing, True) if self.fLabel: if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL: painter.setPen(self.fLabelGradientColor2) painter.setBrush(self.fLabelGradient) painter.drawRect(self.fLabelGradientRect) painter.setFont(self.fLabelFont) painter.setPen(self.fLabelGradientColorT[0 if self.isEnabled() else 1]) painter.drawText(self.fLabelPos, self.fLabel) if self.isEnabled(): normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum) target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) curLayer = int((self.fPixmapLayersCount - 1) * normValue) if self.fPixmapOrientation == self.HORIZONTAL: xpos = self.fPixmapBaseSize * curLayer ypos = 0.0 else: xpos = 0.0 ypos = self.fPixmapBaseSize * curLayer source = QRectF(xpos, ypos, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, source) # Custom knobs (Dry/Wet and Volume) if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL): # knob color colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep*6) colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep*6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) #painter.drawRect(ballRect) tmpValue = (0.375 + 0.75*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_WET: painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) gradient = QConicalGradient(15.5, 15.5, -45) gradient.setColorAt(0.0, colorBlue) gradient.setColorAt(0.125, colorBlue) gradient.setColorAt(0.625, colorGreen) gradient.setColorAt(0.75, colorGreen) gradient.setColorAt(0.76, colorGreen) gradient.setColorAt(1.0, colorGreen) painter.setBrush(gradient) painter.setPen(QPen(gradient, 3)) else: painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(colorBlue) painter.setPen(QPen(colorBlue, 3)) painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (L and R) elif self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R): # knob color color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep*6) # draw small circle ballRect = QRectF(7.0, 8.0, 11.0, 12.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) #painter.drawRect(ballRect) tmpValue = (0.375 + 0.75*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0)) # draw arc if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L: startAngle = 216*16 spanAngle = -252.0*16*normValue else: startAngle = 324.0*16 spanAngle = 252.0*16*(1.0-normValue) painter.setPen(QPen(color, 2)) painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle) # Custom knobs (Color) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR: # knob color color = self.fCustomPaintColor.lighter(100 + self.fHoverStep*6) # draw small circle ballRect = QRectF(8.0, 8.0, 15.0, 15.0) ballPath = QPainterPath() ballPath.addEllipse(ballRect) tmpValue = (0.375 + 0.75*normValue) ballValue = tmpValue - floor(tmpValue) ballPoint = ballPath.pointAtPercent(ballValue) # draw arc startAngle = 216*16 spanAngle = -252*16*normValue painter.setBrush(color) painter.setPen(QPen(color, 0)) painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)) painter.setBrush(color) painter.setPen(QPen(color, 3)) painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle) # Custom knobs (Zita) elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA: a = normValue * pi * 1.5 - 2.35 r = 10.0 x = 10.5 y = 10.5 x += r * sin(a) y -= r * cos(a) painter.setBrush(Qt.black) painter.setPen(QPen(Qt.black, 2)) painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y)) # Custom knobs else: painter.restore() return if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX: self.fHoverStep += 1 if self.fIsHovered else -1 QTimer.singleShot(20, self.update) else: # isEnabled() target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize) painter.drawPixmap(target, self.fPixmap, target) painter.restore()
def getPointOnEdge(self, t): edgePath = QPainterPath(self.beginPoint) edgePath.cubicTo(self.curvePoint1, self.curvePoint2, self.endPoint) return QPointF(edgePath.pointAtPercent(t))
def distance_to_path(point: QPointF, path: QPainterPath, percent: float = 0.0): bp = path.pointAtPercent(percent) return ((bp.x() - point.x())**2.0 + (bp.y() - point.y())**2.0)**0.5
def drawTextAlongCubic(self, lay, painter, filename, msg): fs = lay["defaultFontSize"] font = QFont('Right Chalk', fs) defaultMessage = msg if len(msg) == 0: return c1 = QPointF(lay["x1"], lay["y1"]) c2 = QPointF(lay["x2"], lay["y2"]) c3 = QPointF(lay["x3"], lay["y3"]) c4 = QPointF(lay["x4"], lay["y4"]) path = QPainterPath(c1) path.cubicTo(c2, c3, c4) # painter.drawPath(path) pathLength = path.length() textMetricLength = QFontMetrics(font).width(defaultMessage) fsn = int(fs * pathLength / (textMetricLength) * .95) if fsn > 70: fsn = 70 font = QFont('Right Chalk', fsn) textMetricLength = QFontMetrics(font).width(defaultMessage) messageSpacing = [] defaultMessageM = [] sumMessageSpacing = 0.0 for i in range(len(defaultMessage)): messageSpacing.append(QFontMetrics(font).width(defaultMessage[i])) sumMessageSpacing += messageSpacing[i] for i in range(len(defaultMessage)): messageSpacing[i] = messageSpacing[i] / sumMessageSpacing steps = 0 painter.setFont(font) for i in range(len(defaultMessage)): steps += messageSpacing[i] / 2 point = QPointF(path.pointAtPercent(steps)) angle = path.angleAtPercent(steps) painter.save() painter.translate(point) painter.rotate(-angle) x = -QFontMetrics(font).width(defaultMessage[i]) / 2 y = -QFontMetrics(font).height() / 2 w = QFontMetrics(font).width(defaultMessage[i]) h = QFontMetrics(font).height() r = QRectF(x, y, w, h) painter.setPen(QPen(Qt.white, 2)) painter.drawText(r, defaultMessage[i]) if i % 2 == 0: painter.setPen(QPen(Qt.red, 2)) else: painter.setPen(QPen(Qt.green, 2)) # painter.drawRect(r) painter.restore() steps += messageSpacing[i] / 2