PyQt5 使用 QLabel 实现图像 360度 不间断旋转
当我们需要实现让一个图像 360度 旋转时,比如:音乐播放器中播放时,歌曲封面的旋转效果,你可以尝试使用下面的方法
代码结构
本文中全部代码全在test_QLabel_whirling.py
这一个文件中编码,步骤中有变动的地方会注释标注,无改动的不会重复显示出来,需要看完整代码的,可直接移步到末尾。
一. 创建测试页面
创建一个测试页面,其中主要是放置了2个QLabel
,一个QProgressBar
,其中一个QLabel
,用于实现图像旋转
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_QLabel_whirling.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 图像 360 度旋转
"""
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout, QFrame, QProgressBar
from PyQt5.QtGui import QPixmap, QTransform
from PyQt5.QtCore import QTimer, Qt, QMetaObject, QCoreApplication
class Ui_Whirling(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(712, 76)
self.gridLayout_2 = QGridLayout(Form)
self.gridLayout_2.setObjectName("gridLayout_2")
# 创建一个 QFrame,用于放置其余组件
self.frame = QFrame(Form)
self.frame.setFrameShape(QFrame.StyledPanel)
self.frame.setFrameShadow(QFrame.Raised)
self.frame.setObjectName("frame")
# 网格布局
self.gridLayout = QGridLayout(self.frame)
self.gridLayout.setObjectName("gridLayout")
# 创建一个 QLabel,其实这个没啥用
self.label_2 = QLabel(self.frame)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
# 创建一个 QProgressBar,其实这个没啥用
self.progressBar = QProgressBar(self.frame)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 1, 1, 1, 1)
# 创建一个 QLabel,用于实现图片旋转
self.label = QLabel(self.frame)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 2, 1)
self.gridLayout_2.addWidget(self.frame, 0, 0, 1, 1)
self.retranslateUi(Form)
QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "图片 360° 旋转"))
self.label_2.setText(_translate("Form", "<<--- 左侧图片 360° 旋转"))
self.label.setText(_translate("Form", "图片"))
class GIFRotatingLabel(QWidget, Ui_Whirling):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = GIFRotatingLabel()
w.show()
sys.exit(app.exec_())
测试页面如图:
二. 实现方式
方式一:直接使用一个 旋转的gif
实现
这种方式代码量最小,如这样的gif图
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_QLabel_whirling.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 图像 360 度旋转
"""
class Ui_Whirling(object):
... # 忽略,无改动
class GIFRotatingLabel(QWidget, Ui_Whirling):
"""GIF实现"""
def __init__(self):
super().__init__()
self.setupUi(self)
movie = QMovie(r"image\34.gif") # 替换为你的图像路径
self.label.setMovie(movie)
movie.start()
效果如下,此效果图中的抖动是截图导致的,实际是平滑的:
方式二:使用QTransform
重新创建对象并应用
我们使用 QTimer
定期调用 rotate_image
方法来更新图像的旋转角度。每次调用时,创建一个新的 QTransform
对象并应用旋转,然后更新 QLabel
中的图像。调整定时器的间隔和角度增量,就可以改变旋转速度。
代码中使用的create_rounded_pixmap
方法,是将正方形图片通过设置圆角的方式,修改为圆形,具体代码详情看这里
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_QLabel_whirling.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 图像 360 度旋转
"""
class Ui_Whirling(object):
... # 忽略,无改动
class RotatingLabel(QWidget, Ui_Whirling):
"""QTransform"""
def __init__(self):
super().__init__()
self.setupUi(self)
pixmap = QPixmap(r'image\20.png') # 替换为你的图像路径,且必须是正方形
# 创建圆形图像
self.rounded_pixmap = create_rounded_pixmap(pixmap, pixmap.height() / 2)
self.label.setPixmap(self.rounded_pixmap) # 设置图像
self.label.setFixedSize(pixmap.width(), pixmap.height()) # 设置 QLabel 的固定大小
self.label.setAlignment(Qt.AlignCenter) # 使 QLabel 在中心
self.angle = 0 # 初始角度
# 创建定时器
self.timer = QTimer(self)
self.timer.timeout.connect(self.rotate_image)
self.timer.start(10) # 每10毫秒更新一次
def rotate_image(self):
self.angle = (self.angle + 1) % 360 # 每次增加1度
# transform = QTransform().rotate(self.angle)
# 始终保持几何中心旋转
transform = QTransform().translate(self.rounded_pixmap.width() / 2, self.rounded_pixmap.height() / 2) \
.rotate(self.angle) \
.translate(-self.rounded_pixmap.width() / 2, -self.rounded_pixmap.height() / 2)
rotated_pixmap = self.rounded_pixmap.transformed(transform, mode=1) # 使用平滑缩放
self.label.setPixmap(rotated_pixmap)
效果如下,此效果图中的抖动是截图导致的,实际是平滑的:
四. 完整代码
使用时,只使用self.label
相关的设置即可,完整代码如下:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_QLabel_whirling.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 图像 360 度旋转
"""
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout, QFrame, QProgressBar
from PyQt5.QtGui import QPixmap, QTransform
from PyQt5.QtCore import QTimer, Qt, QMetaObject, QCoreApplication
from lib.rounded_pixmap import create_rounded_pixmap
class Ui_Whirling(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(712, 76)
self.gridLayout_2 = QGridLayout(Form)
self.gridLayout_2.setObjectName("gridLayout_2")
# 创建一个 QFrame,用于放置其余组件
self.frame = QFrame(Form)
self.frame.setFrameShape(QFrame.StyledPanel)
self.frame.setFrameShadow(QFrame.Raised)
self.frame.setObjectName("frame")
# 网格布局
self.gridLayout = QGridLayout(self.frame)
self.gridLayout.setObjectName("gridLayout")
# 创建一个 QLabel,其实这个没啥用
self.label_2 = QLabel(self.frame)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
# 创建一个 QProgressBar,其实这个没啥用
self.progressBar = QProgressBar(self.frame)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 1, 1, 1, 1)
# 创建一个 QLabel,用于实现图片旋转
self.label = QLabel(self.frame)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 2, 1)
self.gridLayout_2.addWidget(self.frame, 0, 0, 1, 1)
self.retranslateUi(Form)
QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "图片 360° 旋转"))
self.label_2.setText(_translate("Form", "<<--- 左侧图片 360° 旋转"))
self.label.setText(_translate("Form", "图片"))
class GIFRotatingLabel(QWidget, Ui_Whirling):
"""GIF实现"""
def __init__(self):
super().__init__()
self.setupUi(self)
movie = QMovie(r"image\34.gif") # 替换为你的图像路径
self.label.setMovie(movie)
movie.start()
class RotatingLabel(QWidget, Ui_Whirling):
"""QTransform"""
def __init__(self):
super().__init__()
self.setupUi(self)
pixmap = QPixmap(r'image\20.png') # 替换为你的图像路径,且必须是正方形
# 创建圆形图像
self.rounded_pixmap = create_rounded_pixmap(pixmap, pixmap.height() / 2)
self.label.setPixmap(self.rounded_pixmap) # 设置图像
self.label.setFixedSize(pixmap.width(), pixmap.height()) # 设置 QLabel 的固定大小
self.label.setAlignment(Qt.AlignCenter) # 使 QLabel 在中心
self.angle = 0 # 初始角度
# 创建定时器
self.timer = QTimer(self)
self.timer.timeout.connect(self.rotate_image)
self.timer.start(10) # 每10毫秒更新一次
def rotate_image(self):
self.angle = (self.angle + 1) % 360 # 每次增加1度
# transform = QTransform().rotate(self.angle)
# 始终保持几何中心旋转
transform = QTransform().translate(self.rounded_pixmap.width() / 2, self.rounded_pixmap.height() / 2) \
.rotate(self.angle) \
.translate(-self.rounded_pixmap.width() / 2, -self.rounded_pixmap.height() / 2)
rotated_pixmap = self.rounded_pixmap.transformed(transform, mode=1) # 使用平滑缩放
self.label.setPixmap(rotated_pixmap)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = RotatingLabel()
# window = GIFRotatingLabel()
window.show()
sys.exit(app.exec_())
标签:Form,self,PyQt5,label,gridLayout,frame,360,QLabel
From: https://www.cnblogs.com/yqbaowo/p/18452115