PySide6:如何调整播放QMovie的QLabel大小并保持影片原宽高比?
在PySide6中实现QLabel显示QMovie时保持宽高比缩放
要实现QMovie(如GIF)在QLabel中随标签大小变化保持原始宽高比缩放,核心是正确获取影片的原始尺寸,并在标签尺寸变化时实时计算适配的缩放尺寸。以下是完整的解决方案:
自定义ScaledMovieLabel类
from PySide6.QtWidgets import QLabel from PySide6.QtCore import Qt, QSize class ScaledMovieLabel(QLabel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._original_movie_size = QSize() self._movie = None # 设置GIF在标签中居中显示 self.setAlignment(Qt.AlignCenter) def setMovie(self, movie): if movie != self._movie: self._movie = movie if self._movie: # 获取影片的原始尺寸(关键:不要用scaledSize()) self._original_movie_size = self._movie.originalSize() # 初始化时执行一次缩放 self._update_movie_scale() # 启动影片播放 self._movie.start() # 调用父类方法绑定影片到标签 super().setMovie(self._movie) def resizeEvent(self, event): super().resizeEvent(event) # 标签尺寸变化时更新缩放 if self._movie and not self._original_movie_size.isNull(): self._update_movie_scale() def _update_movie_scale(self): # 计算适配标签大小的最优尺寸(保持宽高比) scaled_size = self._original_movie_size.scale(self.size(), Qt.KeepAspectRatio) # 设置影片的缩放尺寸 self._movie.setScaledSize(scaled_size)
关键说明
获取原始尺寸的正确方式
你之前使用movie.scaledSize()是错误的——这个方法返回的是已设置的缩放尺寸,默认值为(-1,-1)。正确的做法是使用movie.originalSize(),它会直接返回影片的原始分辨率,确保宽高比计算准确。实时缩放逻辑
在resizeEvent中触发缩放更新,每次标签尺寸变化时,用QSize.scale()方法计算出既适配标签大小、又保持原始宽高比的最大尺寸,再通过QMovie.setScaledSize()应用到影片上。额外优化
- 设置标签对齐方式为
Qt.AlignCenter,让缩放后的GIF在标签中居中显示,避免边缘留白或裁剪。 - 在
setMovie中启动影片播放,确保GIF不会只显示第一帧。
- 设置标签对齐方式为
使用示例
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout from PySide6.QtCore import QMovie import sys if __name__ == "__main__": app = QApplication(sys.argv) window = QWidget() layout = QVBoxLayout(window) label = ScaledMovieLabel() movie = QMovie("example.gif") # 替换为你的GIF路径 label.setMovie(movie) layout.addWidget(label) window.resize(400, 300) window.show() sys.exit(app.exec())
内容的提问来源于stack exchange,提问作者Tranquille
相关产品推荐
相关产品推荐

