首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在缩放QGraphicsItem上设置转换点

在缩放QGraphicsItem上设置转换点
EN

Stack Overflow用户
提问于 2021-10-04 13:26:50
回答 1查看 147关注 0票数 2

我在这里有个问题。

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

在我看来,我必须设置.setTransformationOriginPoint(item.boundingRect().center(),但是,看起来转换是从左上角开始的。

我甚至尝试手动设置这个点,但仍然没有成功。

以下是代码:

代码语言:javascript
运行
复制
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包含从字体太棒了下载并调整为20x20像素的svg。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-04 13:54:35

转换总是通过在(0, 0)上设置原点来创建,并且在使用setTransform()时,项目的transformOriginPoint会被忽略,因为它只用于内部setRotationsetScale函数。

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

  • 创造新的转变;
  • 把它翻译到原点;
  • 采用旋转;
  • 采用标尺;
  • 恢复翻译;

由于您需要进行不对称的缩放( setScale没有提供),所以您需要对新的转换进行同样的调整。

代码语言:javascript
运行
复制
    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)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69436810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档