动画大小 属性 时从中心调整小部件的大小
Resize widget from center when animating the size property
我正在尝试编写一个小部件,该小部件在鼠标悬停时尺寸会略微增大,而在鼠标再次离开时尺寸会减小。
这是我到目前为止想出的:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from random import randrange
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.setLayout(layout)
layout.addWidget(MyItem(), Qt.AlignCenter,
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: #{:02x}{:02x}{:02x}'.format(
randrange(255), randrange(255), randrange(255)
))
# Animation
self._enlarged = False
self.zoom_factor = 1.2
self.anim = QPropertyAnimation(self, b'size')
self.anim.setEasingCurve(QEasingCurve.InOutSine)
self.anim.setDuration(250)
def enterEvent(self, event: QEvent) -> None:
self.resize_anim()
self._enlarged = True
def leaveEvent(self, event: QEvent) -> None:
self.resize_anim()
self._enlarged = False
def resize_anim(self):
if self._enlarged:
new_size = self.baseSize()
else:
new_size = QSize(
int(self.baseSize().width() * self.zoom_factor),
int(self.baseSize().height() * self.zoom_factor)
)
self.anim.setEndValue(new_size)
self.anim.start()
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
它几乎按照我想要的方式工作,我唯一的问题是小部件的大小是从 左上角 而不是 中心 .
我该如何更改?
不应使用大小 属性 设置动画,而应使用几何 属性,因为它是相对于父小部件的,因此您可以设置其几何的动画,使中心保持不变。
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()
我正在尝试编写一个小部件,该小部件在鼠标悬停时尺寸会略微增大,而在鼠标再次离开时尺寸会减小。
这是我到目前为止想出的:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from random import randrange
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.setLayout(layout)
layout.addWidget(MyItem(), Qt.AlignCenter,
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: #{:02x}{:02x}{:02x}'.format(
randrange(255), randrange(255), randrange(255)
))
# Animation
self._enlarged = False
self.zoom_factor = 1.2
self.anim = QPropertyAnimation(self, b'size')
self.anim.setEasingCurve(QEasingCurve.InOutSine)
self.anim.setDuration(250)
def enterEvent(self, event: QEvent) -> None:
self.resize_anim()
self._enlarged = True
def leaveEvent(self, event: QEvent) -> None:
self.resize_anim()
self._enlarged = False
def resize_anim(self):
if self._enlarged:
new_size = self.baseSize()
else:
new_size = QSize(
int(self.baseSize().width() * self.zoom_factor),
int(self.baseSize().height() * self.zoom_factor)
)
self.anim.setEndValue(new_size)
self.anim.start()
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
它几乎按照我想要的方式工作,我唯一的问题是小部件的大小是从 左上角 而不是 中心 .
我该如何更改?
不应使用大小 属性 设置动画,而应使用几何 属性,因为它是相对于父小部件的,因此您可以设置其几何的动画,使中心保持不变。
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()