【QT】在桌面上放个伊芙利特

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_41374099/article/details/102766019

前言

就是像QQ宠物一样,在电脑屏幕上放一个可交互的GIF……提前准备一批透明背景的GIF图和分解出来的透明背景的PNG图


无边框&透明背景窗口

建一个集成QMainWindow或者QWidget的QT项目。UI编辑里删除状态栏、工具栏、菜单栏。放入一个QLablel,我们就是用QLabelsetMovie方法来显示图片。把label设置为右键设置为栅格布局,并且记得右下角的布局属性设置为0
在这里插入图片描述
接着设置窗口透明、无边框、始终置于前面。这样运行会得到一个透明窗口,因为是透明的所以看不到,需要在任务栏关闭。

//widget.cpp
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);


    //无边框//保证窗口一直在前面
    setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
    //透明背景
    setAttribute(Qt::WA_TranslucentBackground);

}

实现窗口可拖动

首先需要填充一下背景,只有被填充的窗口部分才能接受到鼠标点击的信号——到后面我们播放透明背景的GIF图就明白了,透明的部分的窗口是可以穿过的,只有不透明的地方才能交互。

//widget.cpp
void Widget::paintEvent(QPaintEvent *event){
	QPainter p(this);
	//颜色填充
    p.fillRect(6,6,width()-12,height()-12,QColor(232, 236, 247));

	//图片填充
	 //位图填充
    //QPixmap backBmp("../window_try_2/Background.bmp");
    //  p.drawPixmap(6,6,width()-12,height()-12,backBmp,0,0,backBmp.width(),backBmp.height());

}

在这里插入图片描述
可以重写一下mouseMoveEvent输出鼠标坐标,来看看是否接受到了鼠标消息。

接受到了鼠标消息,拖动就是靠这个消息来手动移动窗口。

//widget.h
protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    bool    flag_clicked;        //左鼠标点击实现移动
    QPoint  currentPos;   //屏幕上点击的坐标点
//widget.cpp
void Widget::mouseMoveEvent(QMouseEvent *event){

    //移动窗口
    if(flag_clicked){
        QPoint tempPos = event->globalPos() - currentPos;
        move(pos() + tempPos);
        currentPos = event->globalPos();
    }

}
void Widget::mousePressEvent(QMouseEvent *event){
    if(event->buttons() == Qt::LeftButton){
        //qDebug()<<"flag_clicked=true";
        flag_clicked = true;
        currentPos = event->globalPos();
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *event){

    //qDebug()<<"flag_clicked=false";
    flag_clicked = false;

}

在这里插入图片描述

播放GIF

在这里插入图片描述
文件太大了,只能放截图了。官方公布的两个GIF图,找不到透明背景的,所以只有自己处理了(这个之后讲)

先播放试试效果。使用QMovie类来加载GIF图,再使用QLabel的setMovie方法来显示。

//widget.cpp
    //这个添加到构造函数里
    //播放GIF
    movie=new QMovie("../window_try_4/1.gif");
    movie->setScaledSize(QSize(200,200));//设置GIF大小
    //movie->setSpeed(100);//默认100%原始动画速度
    ui->label->setMovie(movie);
    movie->start();

保存为JPG

为了更好的操作,必须要PNG图。用在线的GIF转JPG没用,因为文件太大,转换出来的都坏了,所以还是自己来转换。
通过获取QMovie对象的当前图像,可以保存为JPG图片。另外每次QMovie对象的帧变化时会发射frameChanged信号,所以我们需要自定义一个槽函数on_saveAsJPG来关联一下。
通过这种方法,可以发现第一个GIF图有111帧,第二个GIF图有158帧……

//widget.cpp
void Widget::on_saveAsJPG(){

    static int i=0;
    if(i<movie->frameCount()){ //避免保存太多
        qDebug()<<"save>"<<i;
        QImage p = movie->currentImage();
        p.save(QString::asprintf("E:/干员1_JPG/1_%d.jpg",i++),"JPG",100);//100表示未压缩
    }
}

抠图变成PNG

无论你是想直接播放几个GIF(下面那步)还是想逐帧播放(下下面那步),都需要抠图(如果有现成的该多好)……

用PS打开一张JPG图片,用多边形套索选择出来。新建一个图层,把选择的内容复制到新的图层中,再把旧的图层删除,保存到PNG文件夹。

[抠图中]

合成几个GIF

拿第一个GIF分开的PNG图做成两个GIF,一个普通播放的,一个特殊交互的。

在鼠标点击后,设置特殊GIF播放标记,关掉普通GIF播放。在特殊GIF播放完前,再次点击不会再触发播放特殊的。通过记录帧数来判断是否播放完,播放完特殊的后,再次初始化标记,并且关掉特殊GIF,开启普通GIF。
——这里还需要关联一下frameChanged信号与paintEvent,因为这个函数并不是每次都会被执行。

//widget.cpp

void Widget::mousePressEvent(QMouseEvent *event){


    if(event->buttons() == Qt::LeftButton){
        //qDebug()<<"flag_clicked=true";
        flag_clicked = true;
        currentPos = event->globalPos();

        if(!flag_special){ //如果之前播放的是普通GIF
            qDebug()<<"special gif";
            flag_special=true;
            movie->stop();
            delete movie;
            movie=new QMovie("../window_try_4/yifulite2.gif");
            movie->setScaledSize(QSize(200,200));//设置GIF大小
            ui->label->setMovie(movie);
            movie->start();
        }

    }
}
void Widget::paintEvent(QPaintEvent *event){

    static int i=0;
    if(flag_special&&i++>=movie->frameCount()){//在播放特殊GIF,并且放完了
        qDebug()<<"normal gif";
        flag_special=false;
        movie->stop();
        delete movie;
        movie=new QMovie("../window_try_4/yifulite1.gif");
        movie->setScaledSize(QSize(200,200));//设置GIF大小
        ui->label->setMovie(movie);
        movie->start();
        i=0;
    }

}

有点难受。。。抠了一天,抠了快12个小时,做的效果并不好。。。

在这里插入图片描述

逐帧绘制以增加交互感

参考:

QT学习之路之Movie动画

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/102766019