Skip to content Skip to sidebar Skip to footer

Resize Widget From Center When Animating The Size Property

I'm trying to code a widget that slightly increases in size on mouse-over and decreases when the mouse leaves again. This is what I have come up with so far: from PyQt5.QtCore impo

Solution 1:

Instead of animating using the size property you should use the geometry property as it is relative to the parent widget, so you can animate its geometry making the center remain invariant.

from PyQt5.QtCore import (
    QAbstractAnimation,
    QEasingCurve,
    QEvent,
    QPropertyAnimation,
    QRect,
    Qt,
)
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (
    QApplication,
    QLabel,
    QMainWindow,
    QSizePolicy,
    QVBoxLayout,
    QWidget,
)

import random


class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setFixedSize(500, 500)

        cent_widget = QWidget()
        self.setCentralWidget(cent_widget)

        layout = QVBoxLayout(cent_widget)
        layout.addWidget(MyItem(), alignment=Qt.AlignCenter)


class MyItem(QLabel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setBaseSize(200, 250)
        self.setMinimumSize(self.baseSize())
        self.resize(self.baseSize())

        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self.setStyleSheet(
            "background: {}".format(QColor(*random.sample(range(255), 3)).name())
        )

        # Animation
        self.zoom_factor = 1.2

        self.anim = QPropertyAnimation(self, b"geometry")
        self.anim.setEasingCurve(QEasingCurve.InOutSine)
        self.anim.setDuration(250)

    def enterEvent(self, event: QEvent) -> None:

        initial_rect = self.geometry()
        final_rect = QRect(
            0,
            0,
            int(initial_rect.width() * self.zoom_factor),
            int(initial_rect.height() * self.zoom_factor),
        )
        final_rect.moveCenter(initial_rect.center())

        self.anim.setStartValue(initial_rect)
        self.anim.setEndValue(final_rect)
        self.anim.setDirection(QAbstractAnimation.Forward)
        self.anim.start()

    def leaveEvent(self, event: QEvent) -> None:
        self.anim.setDirection(QAbstractAnimation.Backward)
        self.anim.start()


if __name__ == "__main__":
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec()

Post a Comment for "Resize Widget From Center When Animating The Size Property"