1

我在这里遇到问题。

在给定的代码中,动画和转换工作完美。但是,我想要设置转换点。

据我说,我必须设置.setTransformationOriginPoint(item.boundingRect().center(),但看起来转换是从左上角发生的。

我什至尝试手动设置点,但仍然没有用。

这是代码:

from typing import Any
from PyQt6.QtCore import QPointF, QSequentialAnimationGroup, Qt, pyqtSignal
from PyQt6.QtGui import QColor, QEnterEvent, QMouseEvent , QTransform
from PyQt6.QtWidgets import QApplication, QGraphicsColorizeEffect, QGraphicsScene, QGraphicsView, QMainWindow, QWidget
from functools import partial
from PyQt6.QtSvgWidgets import QGraphicsSvgItem

from typing import Any, Callable
from PyQt6.QtCore import QEasingCurve, QPoint, QPropertyAnimation, QRect, QVariantAnimation
from PyQt6.QtWidgets import QGraphicsOpacityEffect, QWidget

class Animation:
    def variantAnimation(startValue: Any , endValue: Any , duration: int , callback: Callable) -> QVariantAnimation:
        animation = QVariantAnimation()

        animation.setStartValue(startValue)

        animation.setEndValue(endValue)

        animation.setDuration(duration)

        animation.setEasingCurve(QEasingCurve.Type.InOutQuad)

        animation.valueChanged.connect(callback)

        return animation


class Rounded_Jolly_Button(QGraphicsView):
    clicked = pyqtSignal()
    
    def __init__(self , parent: QWidget , location: str):
        super().__init__(parent)

        self.location = location

        self.setStyleSheet("background-color: #2E3440; border-radius: 22px")

        self.setFixedSize(45 , 45)

        self.setCursor(Qt.CursorShape.PointingHandCursor)

        self._scene = QGraphicsScene()

        self.setScene(self._scene)

        self._scene.setSceneRect(0 , 0 , 40 , 40)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)

        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)

        self.setStyles()

    def setStyles(self):
        color = QGraphicsColorizeEffect()

        color.setColor(QColor("#D8DEE9"))

        svg = QGraphicsSvgItem("./assets/google.svg")

        svg.setAcceptHoverEvents(True)

        svg.setPos(10 , 10)

        svg.setGraphicsEffect(color)

        self._scene.addItem(svg)

        svg.setTransformOriginPoint(svg.boundingRect().center())

        self.animations = QSequentialAnimationGroup()

        self.animations.addAnimation(Animation.variantAnimation(QPointF(1.0 , 1.0) , QPointF(1.25 , 0.75) , 270 , partial(self.updateTransform , svg)))

        self.animations.addAnimation(Animation.variantAnimation(QPointF(1.25 , 0.75) , QPointF(.75 , 1.25) , 90 , partial(self.updateTransform , svg)))

        self.animations.addAnimation(Animation.variantAnimation(QPointF(.75 , 1.25) , QPointF(1.15 , .85) , 90 , partial(self.updateTransform , svg)))

        self.animations.addAnimation(Animation.variantAnimation(QPointF(1.15 , 0.85) , QPointF(.95 , 1.05) , 135 , partial(self.updateTransform , svg)))

        self.animations.addAnimation(Animation.variantAnimation(QPointF(.95 , 1.05) , QPointF(1.05 , 0.95) , 90 , partial(self.updateTransform , svg)))

        self.animations.addAnimation(Animation.variantAnimation(QPointF(1.05 , 0.95) , QPointF(1 , 1) , 225 , partial(self.updateTransform , svg)))

    def enterEvent(self, event: QEnterEvent) -> None:
        self.animations.start()

        return super().enterEvent(event)

    def mousePressEvent(self, ev: QMouseEvent) -> None:
        if(ev.button() == Qt.MouseButton.LeftButton):
            self.clicked.emit()

        return super().mousePressEvent(ev)

    def updateTransform(self , target: QGraphicsSvgItem , newValue: Any):
        target.setTransform(QTransform().scale(newValue.x() , newValue.y()))


def window():
    app = QApplication([])

    window = QMainWindow()

    parent = QWidget()

    button = Rounded_Jolly_Button(parent , None)

    window.setCentralWidget(parent)

    window.show()
    
    exit(app.exec())
    
if __name__ == '__main__':
   window()

注意:./assets/google.svg包含从Font Awesome下载并调整大小为 20x20 像素的 svg

4

1 回答 1

2

变换总是使用设置在 的原点创建(0, 0),并且在使用 时setTransform()transformOriginPoint忽略该项,因为它仅用于内部setRotationsetScale函数。

在内部,当旋转或缩放设置为 QGraphicsItem 时,转换以下列方式应用:

  • 创造一个新的转变;
  • 将其翻译到原点;
  • 应用旋转;
  • 应用量表;
  • 恢复翻译;

由于您需要进行非对称缩放(setScale不提供),因此您需要对新转换执行相同的操作。

    def updateTransform(self , target: QGraphicsSvgItem , newValue: Any):
        origin = target.transformOriginPoint()
        transform = QTransform().translate(origin.x(), origin.y())
        transform.scale(newValue.x(), newValue.y())
        transform.translate(-origin.x(), -origin.y())
        target.setTransform(transform)
于 2021-10-04T13:54:35.097 回答