设置缩放 QGraphicsItem 的变换点

2024-05-04

我这里有个问题。

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

根据我的说法,我必须设置.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()

Note: ./assets/google.svg包含从下载的 svg字体真棒 https://fontawesome.com/v5.15/icons/google?style=brands并将大小调整为 20x20 像素


始终使用设置的原点创建变换(0, 0),并且,当使用setTransform(), 这几项transformOriginPoint被忽略,因为它仅用于内部setRotation and setScale功能。

在内部,当将旋转或缩放设置为 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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设置缩放 QGraphicsItem 的变换点 的相关文章