QT 如何在QPushButton上播放gif(终极版)

news2024/11/17 0:47:12

在平时浏览网站,或者使用软件的时候,经常可以见到:在点击了某个按钮之后,按钮上会显示动图以及提示文字。在QT中,比较常见且简单的做法就是:给按钮设置一个layout,然后在这个layout里面添加QLabel(作为QMovie的载体),以及用于显示文字的QLabel。该方案可参考:https://blog.csdn.net/hellokandy/article/details/120043562

但本文将采取另外一种方式(编写一个用于播放Gif 的QPushButton类)来实现,原生的按钮只要提升为该类即可。

1、效果图

在这里插入图片描述

2、GifPushButton

1、GifPushButton.h

#ifndef GIFPUSHBUTTON_H
#define GIFPUSHBUTTON_H
#include <QWidget>
#include <QPushButton>

class QMovie;
class GifPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit GifPushButton(QWidget *parent = nullptr);
    ~GifPushButton(){}
    //
    void SetMovie(const QString &fileName);
    void SetMovie(QMovie *movie);
    QMovie *GetMovie() const;
    //
    void Start();
    void Stop();
    //
signals:
    void movieChanged();

protected:
    void showEvent(QShowEvent *event) override;
    void hideEvent(QHideEvent *event) override;

private slots:
    void OnFrameChanged(int frameNumber);
private:
    QMovie *m_movie = nullptr;
    bool m_movieResized = false;
};

#endif // GIFPUSHBUTTON_H

2、GifPushButton.cpp

#include "gifpushbutton.h"
#include <QMovie>
#include <QDebug>

GifPushButton::GifPushButton(QWidget *parent)
    : QPushButton(parent)
    , m_movie(nullptr)
{

}

void GifPushButton::SetMovie(const QString &fileName)
{
    auto movie = new QMovie(this);
    movie->setFileName(fileName);
    SetMovie(movie);
}

void GifPushButton::SetMovie(QMovie *movie)
{
    if(!movie){
        return;
    }

    if(movie == m_movie){
        return;
    }

    if(m_movie)
    {
        m_movie->stop();
        disconnect(movie, &QMovie::frameChanged, this, &GifPushButton::OnFrameChanged);
    }

    if(movie->parent() != this){
        movie->setParent(this);
    }
    movie->jumpToFrame(0);
    m_movie = movie;
    connect(movie, &QMovie::frameChanged, this, &GifPushButton::OnFrameChanged);
    connect(movie, &QMovie::destroyed, this, [](QObject *object){
        Q_UNUSED(object);
        qDebug() << "movie destroyed";
    });
    //
    emit movieChanged();
}

QMovie *GifPushButton::GetMovie() const
{
    return m_movie;
}

void GifPushButton::Start()
{
    if(m_movie){
        m_movie->start();
    }
}

void GifPushButton::Stop()
{
    if(m_movie){
        m_movie->stop();
        setIcon(QIcon());
    }
}

void GifPushButton::showEvent(QShowEvent *event)
{
    if(m_movie){
       m_movie->start();
    }
    //GifPushButton::showEvent(event);
}

void GifPushButton::hideEvent(QHideEvent *event)
{
    if(m_movie){
        m_movie->stop();
    }
    //GifPushButton::hideEvent(event);
}

void GifPushButton::OnFrameChanged(int frameNumber)
{
    if(!m_movie){
        return;
    }

    if(!m_movieResized)
    {
        int len = qMin(width(), height());
        QSize sz = QSize(len, len);
        m_movie->setScaledSize(sz);
        QRect rect = m_movie->frameRect();
        //
        m_movieResized = true;
        qDebug() << sz << rect.size();
    }

    QPixmap pix = m_movie->currentPixmap();
    setIcon(QIcon(pix));
}

3、如何使用

#include "maindialog.h"
#include "ui_maindialog.h"

MainDialog::MainDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::MainDialog)
{
    ui->setupUi(this);
    //
    ui->button_loading->setFixedSize(150, 36);
    ui->button_downloading->setFixedSize(150, 36);
    ui->button_dancing->setFixedSize(150, 36);
    //
    ui->button_loading->SetMovie(":/image/loading.gif");
    ui->button_downloading->SetMovie(":/image/downloading.gif");
    ui->button_dancing->SetMovie(":/image/dancing.gif");
    //from qss style
    ui->button_loading->setProperty("button_type", "120x48");
}

MainDialog::~MainDialog()
{
    delete ui;
}

void MainDialog::on_button_start_clicked()
{
    ui->button_loading->Start();
}

void MainDialog::on_button_stop_clicked()
{
    ui->button_loading->Stop();
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ListBox显示图片的一些问题

相关&#xff1a;http://t.csdnimg.cn/xTnu8 显示图片的方案就是&#xff1a;自定义一个Photo类&#xff0c;里面有属性Source&#xff1b;View再绑定ViewModel中的Photo集合&#xff0c;再到View中给ListView设置数据模板 关键点&#xff1a;这样做很容易忘记写数据模板 数据…

4款实用性前端动画特效分享(附在线演示)

分享4款非常不错的项目动画特效 其中有jQuery特效、canvas特效、CSS动画等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 全屏图片视差旋转切换特效 基于anime.js制作全屏响应式的图片元素布局&#xff0c;通过左…

docker部署在线音乐播放器

YesPlayMusic是一款高颜值的第三方网易云播放器 部署 下载镜像 docker pull fogforest/yesplaymusicdocker-compose部署 vim docker-compose.yaml version: 3 services:yesplaymusic:container_name: yesplaymusicimage: fogforest/yesplaymusicports:- 7950:80restart: a…

wxss和css的区别

目录 1. 语法差异 2. 尺寸单位 3. 样式导入 WXSS 示例代码&#xff1a; CSS 示例代码&#xff1a; 4. 组件和属性的支持 总结 WXSS (WeiXin Style Sheets) 和 CSS (Cascading Style Sheets) 都是用于描述文档样式的语言&#xff0c;但它们在微信小程序和网页开发中有一些…

数据结构从入门到精通——堆

堆 前言一、二叉树的顺序结构及实现 (堆&#xff09;1.1二叉树的顺序结构1.2堆的概念及结构 二、堆的练习题答案 三、堆的实现3.1堆向下调整算法3.2堆的创建3.3建堆时间复杂度3.4堆的插入3.5堆的删除3.6堆的代码实现 四、堆的具体实现代码Heap.hHeap.cTest.c堆的初始化堆的销毁…

二叉树相关题目

1.中序遍历和后序遍历构建二叉树&#xff1b; TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {//判空if(postorder.size() 0) return nullptr;//找到后序的最后元素就是根节点以及栈来存放数据auto rootnew TreeNode(postorder[post…

Hadoop大数据应用:Linux 部署 MapReduce 与 Yarn

目录 一、实验 1.环境 2.Linux 部署 MapReduce 3.Linux 部署 Yarn 4.Linux 调用大数据集群分析数据 二、问题 1.hadoop 的启动和停止命令 2.HDFS 使用命令 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构软件版本IP备注hadoop NameNode &#xf…

基于单片机的指纹采集识别系统设计

目 录 摘 要 I Abstract II 引 言 3 1 硬件选择与设计 5 1.1 总体设计及方案选择 5 1.1.1主控单片机选择 5 1.1.2传感器模块选择 6 1.1.3显示器模块选择 6 1.2 系统总体设计 7 2 系统硬件电路设计 8 2.1 系统主电路设计 8 2.1.1 主体电路设计 8 2.1.2 单片机最小系统设计 8 2.…

python的函数与类的定义

目录 1.函数 1.函数的定义 2.输入参数与输出参数的类型 3.输入和输出多个参数 1.普通参数 2.含有任意数量的参数 3.关键字参数 4.普通参数与多个参数的结合 2.类 1.类的定义 2.类的实例化 3.继承 1.函数 1.函数的定义 def 函数名(输入参数): 文档字符串 函数体 …

ElasticSearch深度分页问题如何解决

文章目录 概述解决方法深度分页方式from size深度分页之scrollsearch_after 三种分页方式比较 概述 Elasticsearch 的深度分页问题是指在大数据集上进行大量分页查询时可能导致的性能下降和资源消耗增加的情况。这种情况通常发生在需要访问大量数据的情形下&#xff0c;比如用…

finalshell连接cetOS7卡顿(配置完静态IP后出现的问题)

检查后的原因是:ssh服务端在连接时自动检测dns环境是否一致&#xff0c;这里将此次检测关闭即可 解决方案如下: vi /etc/ssh/sshd_config(打开后一直回车键到最下边)找到DNS&#xff0c;改为useDNS no&#xff08;默认为#useDNSyes&#xff09; 修改后重启服务&#xff1a; sys…

基于Java+SpringBoot+vue+element实现前后端分离玩具商城系统

基于JavaSpringBootvueelement实现前后端分离玩具商城系统 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文…

Pytorch入门实战 P2-CIFAR10彩色图片识别

目录 一、前期准备 1、数据集CIFAR10 2、判断自己的设备&#xff0c;是否可以使用GPU运行。 3、下载数据集&#xff0c;划分好训练集和测试集 4、加载训练集、测试集 5、取一个批次查看下 6、数据可视化 二、搭建简单的CNN网络模型 三、训练模型 1、设置超参数 2、编…

【Vue2】slot 插槽全家桶

插槽-默认插槽 插槽的基本语法 组件内需要定制的结构部分&#xff0c;改用<slot></slot>占位使用组件时, <MyDialog></MyDialog>标签内部, 传入结构替换slot给插槽传入内容时&#xff0c;可以传入纯文本、html标签、组件 插槽-默认值 封装组件时&am…

Nginx的日志怎么看,在哪看,access.log日志内容详解

Nginx 的日志文件通常位于服务器的文件系统中&#xff0c;具体位置可能因配置而异。以下是查看 Nginx 日志的几种方法&#xff1a; 1、查看访问日志&#xff1a;在默认配置下&#xff0c;Nginx 的访问日志文件路径为 /var/log/nginx/access.log。您可以通过命令 sudo cat /var…

创新营销的新篇章:企业如何通过VR虚拟发布会提升品牌影响力

在数字化转型的浪潮中&#xff0c;VR虚拟发布会作为一种新兴的营销手段&#xff0c;正逐渐成为企业品牌推广和产品发布的重要选择。通过利用虚拟现实技术&#xff0c;企业能够在虚拟空间中举办发布会&#xff0c;为参与者提供沉浸式的体验。 一、创新体验&#xff1a;虚拟空间的…

linux系统对于docker容器的监控

容器监控 容器监控原生命令操作问题 容器监控三剑客CAdvisorInfluxDBGranfana compose编排监控工具新建目录创建CIG.yml文件启动docker-compose测试 容器监控 CAdvisorInfluxDBGranfana 原生命令 操作 docker stats问题 通过docker stats命令可以很方便的看到当前宿主机上所…

【黑马程序员】Python文件操作

文章目录 文件操作文件编码什么是编码为什么要使用编码 文件的读取openmodel常用的三种基础访问模式读操作相关方法 文件的写入注意代码示例 文件操作 文件编码 什么是编码 编码就是一种规则集合&#xff0c;记录了内容和二进制间进行互相转换的规则 最常用的是UTF-8编码 …

魔法手链(burnside+矩阵优化+dp acwing 3134)

题目&#xff1a;3134. 魔法手链 - AcWing题库 思路&#xff1a; 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #i…

史上最全Spring教程,从零开始带你深入♂学习(三)—

减少数据处理量&#xff0c;提高查询效率 (一)使用Limit分页 –从第2个开始查询&#xff0c;每一页10个 select * from user limit 2,10 –从第0个开始查询&#xff0c;每一页10个 SELECT * from user limit 10; 领取资料 (二)使用Mybatis实现分页&#xff0c;核心SQL 1、编…