Search code examples
pyqtpyqt5

Change box size with mouse hover in PyQt5


I want to create a box that will enlarge when I hover over it with the mouse i have this code...

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setFixedSize(600, 600)

        widget = QWidget()
        self.setCentralWidget(widget)

        layout = QVBoxLayout()
        widget.setLayout(layout)


        item = MyItem()
        layout.addWidget(item, Qt.AlignCenter,Qt.AlignCenter)


class MyItem(QLabel):

    def __init__(self):
        super().__init__()
        self.setBaseSize(30, 30)
        self.setMinimumSize(self.baseSize())
        self.resize(self.baseSize())

        self.setStyleSheet('background: blue')

        self._enlarged = False

        self.anim = QPropertyAnimation(self, b'size')
        self.anim.setDuration(200)

    def enterEvent(self, event):
        self.resize_anim()
        self._enlarged = True

    def leaveEvent(self, event):
        self.resize_anim()
        self._enlarged = False

    def resize_anim(self):
        if self._enlarged:
            newSize = self.baseSize()
        else:
            newSize = QSize(int(self.baseSize().width() * 10),
            int(self.baseSize().height() * 10))
        self.anim.setEndValue(newSize)
        self.anim.start()


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

My problem is that in this box, changing the scale of the box only happens from the top left

And What I want is to choose the starting point of rescaling the box myself

For example, from the top right or the bottom left or the top center

Should I use a specific class?


Solution

  • Resizing doesn't consider the widget size hints and policies, which are essential for layout managers.

    Use minimumSize as target property for the animation, not size:

            self.anim = QPropertyAnimation(self, b'minimumSize')
    

    Also, the Qt.AlignCenter flag already combines horizontal and vertical alignments, and you're actually using the first occurrence as the stretch argument of addWidget(), which is obviously inopportune; just use the alignment value with the proper keyword:

            layout.addWidget(item, alignment=Qt.AlignCenter)
    

    Finally, if you just want to reverse the animation, use setDirection().