首页 > 其他分享 >PyQt5 使用 QLabel 实现图像 360度 不间断旋转

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

时间:2024-10-08 17:59:57浏览次数:1  
标签:Form self PyQt5 label gridLayout frame 360 QLabel

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_())

测试页面如图:
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, 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_())


本文章的原文地址
GitHub主页

标签:Form,self,PyQt5,label,gridLayout,frame,360,QLabel
From: https://www.cnblogs.com/yqbaowo/p/18452115

相关文章

  • Pyqt5+SQLite
    通常在做业务逻辑时会遇到,如何在界面上对数据库信息进行操作的问题。这里我们选用SQLite,它是一种嵌入式数据库,以单个独立的文件形式存储数据,适用于Pyqt5的开发。下面做一个小案例,将数据库信息显示在界面中。1.创建数据库代码案例如下(创建一个用户信息表):conn=sqlite3.con......
  • 文心一言 VS 讯飞星火 VS chatgpt (360)-- 算法导论24.3 2题
    二、请举出一个包含负权重的有向图,使得Dijkstra算法在其上运行时将产生不正确的结果。为什么在有负权重的情况下,定理24.6的证明不能成立呢?定理24.6的内容是:Dijkstra算法运行在带权重的有向图时,果所有权重为非负值,则在算法终止时,对于所有结点,我们有。如果要写代码,请用go......
  • 基于PyQt5和SQLite的数据库操作程序
    基于PyQt5和SQLite的数据库操作程序:功能解析在现代办公和数据处理中,数据库操作是不可或缺的一部分。然而,传统的数据库管理工具往往界面复杂,操作繁琐,对于非专业人士来说存在一定的学习曲线。为了解决这个问题,我们开发了一款基于PyQt5和SQLite的数据库操作程序。该程序提供了一......
  • PyQt5 使用 QFrame 实现页面类抽屉式的进入与退出的动画
    PyQt5使用QFrame实现页面类抽屉式的进入与退出的动画当多个页面切换,但是又不想每个页面里的内容只是简单的出现与消失,则可以使用这个QPropertyAnimation动画代码结构本文中全部代码全在test_QFrame_Animation.py这一个文件中编码,步骤中有变动的地方会注释标注,无改动的不会重......
  • 骨传导耳机品牌排行榜分享:360度实测分析10款抢手骨传导耳机!
    随着科技的不断进步和人们生活方式的变化,骨传导耳机以其独特的传声方式和开放式设计,逐渐成为运动爱好者、户外活动家以及听力障碍人士的新宠。不同于传统耳机将声音直接导入耳道,骨传导耳机通过振动颅骨将声音传递至内耳,不仅能够保护听力,还能在享受音乐的同时保持对外界环境的感......
  • LMZ23605具备 36V 最高输入电压的 5A SIMPLE SWITCHER®易电源电源模块
    LMZ23605SIMPLESWITCHER®易电源电源模块是一种易于使用的降压直流/直流解决方案,具有驱动高达5A的负载的能力。LMZ223605采用创新封装模式,提高了散热性能,可以手工或机器焊接。LMZ23605可以工作于6V和36V之间的输入电压轨,并提供低至0.8V的可调高精度输出电压。LMZ23605只......
  • PyQt项目实战-(Pyqt5+mysql制作一个TODO清单 第一部分)
    PyQt项目实战Pyqt5实现todolist工作待办的增、改、删、查功能,连接mysql存储数据(待办事项)。目录目录        1.界面设计    2.功能实现    3.界面各Button点击事件和槽函数的链接    4.mysql数据库操作工具类    5.槽函数实现......
  • Mimikatz的使用及免杀方向(过360,火狐和WindowsDefinder)
    一.Mimikatz加修改注册表绕过LSA保护(暂不考虑EDR和WD)Mimikatz原理:Mimikatz通过逆向获取存储在lsass.exe进程中的明文登录密码。(lsass.exe用于本地安全和登陆策略)。首先使用Mimikatz抓取时必须是管理员权限,在win10,win11,win2012等版本中,系统会开启LSA保护,明文密码字段会显示nul......
  • PyQt5 使用 QLabel 实现对图片圆角或者圆形图片
    PyQt5使用QLabel实现对图片圆角或者圆形图片本文圆角实现代码,是基于Qt处理图片:设置图片圆角样式,支持全圆角和部分圆角这篇文章将C++用Python重写得到,感谢!!实现方法就是使用QPainter与QPainterPath,将原QPixmap对象,先裁剪出一个圆角QPixmap对象并返回,最后通过QLabel的setPixmap......
  • Pyqt5 修改表格排序箭头
    实现效果:代码fromchatgptimportsysfromPyQt5.QtWidgetsimportQApplication,QTableWidget,QTableWidgetItem,QVBoxLayout,QWidgetfromPyQt5.QtCoreimportQtclassTableDemo(QWidget):def__init__(self):super().__init__()#创建表......