PyQt5 使用 QLabel 实现图像 360度 不间断旋转

news/2024/10/8 18:09:53/文章来源:https://www.cnblogs.com/yqbaowo/p/18452115

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, QCoreApplicationclass 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.translateForm.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 sysapp = QApplication(sys.argv)w = GIFRotatingLabel()w.show()sys.exit(app.exec_())

测试页面如图:
image

二. 实现方式

方式一:直接使用一个 旋转的gif实现

这种方式代码量最小,如这样的gif图
image

#!/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()

效果如下,此效果图中的抖动是截图导致的,实际是平滑的:
image

方式二:使用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)

效果如下,此效果图中的抖动是截图导致的,实际是平滑的:
image

四. 完整代码

使用时,只使用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, QCoreApplicationfrom lib.rounded_pixmap import create_rounded_pixmapclass 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.translateForm.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 sysapp = QApplication(sys.argv)window = RotatingLabel()# window = GIFRotatingLabel()window.show()sys.exit(app.exec_())

本文章的原文地址
GitHub主页

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/810096.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

systemverilog笔记

变量类型变量名 状态数 是否带符号 比特数logic 4 无 1bit 2 无 1byte 2 有 8shortint 2 有 16int 2 有 32longint 2 有 64integer 4 有 32time 4 无 64$isunknown(表达式):在表达式任意位出现X或者Z时返回1。 数组 数组初始化 使用单引号加大括号数组遍历 $size(数组)会返回

DSP概述及应用——TMS320DM6437ZDU4、TMS320DM6437ZWT6、TMS320DM6437ZWT7数字媒体处理器

TMS320DM6437采用基于超标量架构的C64x+内核,具有高效的乘法累加单元和多格式指令集,能够在单个时钟周期内执行两条指令,大大提高了运算速度和效率。概述:TMS320DM6437是一款DSP芯片,具有强大的处理能力和丰富的功能模块。 TMS320DM6437采用基于超标量架构的C64x+内核,具…

csp-s模拟10

rank 31,垫底了,T1 0pts,T2 18pts,T3 0pts,T4 50pts 状态有点不好,策略有问题,T4是可以切的,但是不知道为什么弃了。T1不会线性基寄。T3 奇怪结论题,T2 结论题。 在猜结论上还是不行。 T1 欧几里得的噩梦 用到了线性基线性无关的性质,将两个数连边,把环去掉,并查集判…

Kubernetes的Pod调度:让你的应用像乘坐头等舱!

一、Kubernetes 中 Pod 调度的重要性 在 Kubernetes 的世界里,Pod 调度就像是一个繁忙的交通指挥官,负责把小车(也就是我们的 Pod)送到最合适的停车位(节点)。调度不仅关乎资源的合理利用,还关乎应用的“生死存亡”,下面让我们来看看为什么调度这么重要。资源优化: 想象…

二叉树的概念、表示法、性质和操作

本文记述了二叉树的基本概念、表示法、性质和操作。 ◆ 概念 二叉树(以下也简称树)是一种存放多个元素的数据结构。每个元素称为结点,每个结点有左、右两个链接,每个链接要么指向其他结点,要么是空链接。 某个结点是它的左、右链接指向的结点的父结点,被指向的结点是其父…

Springboot中统一启动多个socketIO

前言 这篇随笔属实没想到一个好名字,起因是在项目中遇到了一个springboot服务会发出多个socket服务的场景,而且我们使用的是socketIO服务,为了减少调试工作和重复的开发工作,让开发在项目中专注于业务编写,因此封装了一个在启动springboot服务时,自动创建socketIONamespa…

CSP 模拟9

CSP 模拟9 我也不明白学校模拟赛什么命名逻辑,凑合着看吧最唐的一集 邻面合并 这个直接状压就做完了,赛时早早想到做法,但是因为自己太唐把 \(0\) 写成 \(1\),在优秀大样例的助攻下挂掉 \(50\)点击查看代码 #include<bits/stdc++.h> using namespace std; using llt=…

南沙C++信奥赛陈老师解一本通题 1297:公共子序列

​【题目描述】我们称序列Z=<z1,z2,...,zk>Z=<z1,z2,...,zk>是序列X=<x1,x2,...,xm>X=<x1,x2,...,xm>的子序列当且仅当存在严格上升的序列<i1,i2,...,ik><i1,i2,...,ik>,使得对j=1,2,...,k,有xij=zjxij=zj。比如Z=<a,b,f,c> 是X=&l…

语音生成公司 ElevenLabs 估值达 30 亿美元;OpenAI Realtime API 很好也很贵丨RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编…

万兆加速计算卡设计资料保存:372-基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台

一、板卡概述 基于V7的高性能PCIe信号处理板,板卡选用Xilinx 公司Virtex7系列FPGA XC7VX690T-2FFG1761C为处理芯片,板卡提供两个标准FMC插槽,适用于高性能采集、回放以及相关处理。通过连接不同的FMC子卡的方式,可实现不同形式的数据采集、回放、处理的功能模块。板卡…

打造一站式应用内支付体验,助力开发者商业增长

随着移动互联网的发展,应用内支付已成为数字经济的重要组成部分。用户越来越追求便捷的支付体验,应用内支付服务提供的购买和订阅等能力满足了用户快速、无缝的支付需求,方便用户一站式完成交易,帮助开发者实现收入多元化。 HarmonyOS SDK应用内支付服务(IAP Kit)为用户精…

使用GRUB Multiboot2引导自制操作系统

使用GRUB Multiboot2引导自制操作系统 前言 之前花了一周时间,从头学习了传统 BIOS 的启动流程。惊讶于背后丰富的技术细节的同时,也感叹 x86 架构那厚重的历史包袱。毕竟,谁能想到,一个现代 CPU 竟然需要通过操作“键盘控制器寄存器”来启用一条地址线呢。 最终,出于兼容…