[置顶] Qt实现移入移出与淡入淡出效果

在用Qt做一些客户端时,经常需要实现循环播放一组图文,实现一些广告、步骤引导等效果;

而直接切换又比较生硬,需要加上一些常用的效果,比如淡入淡出效果、平移效果(移入移出)等等;

可以使用QMovie与QGraphicsOpacityEffect与定时器QTimer可以实现这样的效果,可以按你所需,自由实现这些效果;

这里给出一个例子,主要实现了淡入淡出效果与平移效果(上下左右自由组合):

#ifndef SWITCHPICTURE_H
#define SWITCHPICTURE_H

#include <QTimer>
#include <QWidget>
#include <QGraphicsOpacityEffect>
#include <QLabel>
#include <QMovie>

enum CTRLTYPE//控件类型,图片与文字
{
    TEXT,
    IMAGE
};

enum MOVEWAY//平移类型
{
    NONE,
    LEFTTORIGHT,
    RIGHTTOLEFT,
    UPTODOWN,
    DOWNTOUP
};

class SwitchPicture : public QWidget
{
    Q_OBJECT
public:
    explicit SwitchPicture(CTRLTYPE CtrlType = TEXT, QTimer *tm_switch = NULL, QWidget *parent = 0);

public:
    QTimer    *tm_switch;//示意图文切换定时器
    CTRLTYPE  CtrlType;

public:
    QLabel    *lb_picture;//示意图
    QMovie    *mv_media;//多媒体播放
    long      switchmsec;//示意图切换定时器切换间隔(毫秒数)
    long      staymsec;//示意图停留时间(毫秒数)
    QGraphicsOpacityEffect *pictureeffect;//示意图透明度样式
    double    opacity;//透明度值
    double    opacityinterval;//淡入淡出透明度变化间隔
    long      switchcase;//淡入淡出中间状态标志
    long      switchturn;//示意图标号
    long      pageindex;//页面序号{0,1,2...}
    QList<QList<QString>> pictureresourceslist;//示意图与文字说明容器
    MOVEWAY   movein;
    MOVEWAY   moveout;

public:
    //*初始化与切换*//
    void initPage(long pageindex);//初始化页面:停止计时器,初始化示意图与文字提示,然后初始化画面效果
    void initOpacityWithTimer();//初始化画面效果,并打开计时器开启切换效果
    void switchToNext(long nextturn);//切换到对应图片或文字
    void setPictureOpacity();//设置透明度与位移效果
    //*设置切换效果参数*//
    void setOpacityInterval(double opacityinterval = 0.05);//设置透明度渐变粒度
    void setSwitchMsec(long switchmsec = 30, long staymsec = 3000);//设置渐变计时器时间与停留时间
    void addPictureResources(QList<QString> reslist);//添加播放图集
    void clearPictureResources();//清空播放图集
    void setTextStyle(QFont font, QPalette palette);//设置文字显示时的字体与颜色
    void setMoveWay(MOVEWAY movein, MOVEWAY moveout);//设置移入移出的方向

signals:

public slots:
    void on_pictureswitching();//切换响应事件

protected:
    virtual void resizeEvent(QResizeEvent *event);

};

#endif // SWITCHPICTURE_H

#include "SwitchPicture.h"

SwitchPicture::SwitchPicture(CTRLTYPE CtrlType, QTimer *tm_switch, QWidget *parent) :
    QWidget(parent),
    tm_switch(tm_switch),
    CtrlType(CtrlType),
    movein(NONE),
    moveout(NONE),
    opacityinterval(0.05),
    switchmsec(30),
    staymsec(3000)
{
    if (parent)
    {
        this->setGeometry(QRect(0,0,parent->width(),parent->height()));
    }
    //示意图
    lb_picture = new QLabel(this);
    lb_picture->setAlignment(Qt::AlignCenter);
    lb_picture->setGeometry(QRect(0,0,this->width(),this->height()));

    //多媒体播放
    mv_media = new QMovie(this);
    lb_picture->setMovie(mv_media);

    if (!this->tm_switch)
    {
        this->tm_switch = new QTimer(this);
    }

    connect(this->tm_switch, SIGNAL(timeout()), this, SLOT(on_pictureswitching()));
    pictureeffect = new QGraphicsOpacityEffect();//示意图透明度样式

}

//初始化页面:停止计时器,初始化示意图与文字提示,然后初始化画面效果
void SwitchPicture::initPage(long pageindex)
{
    //重置定时器以及相关参数
    tm_switch->stop();
    this->pageindex = pageindex;
    if (pictureresourceslist.length() > pageindex)
    {
        if (pictureresourceslist[pageindex].length() > 0)
        {
            switch(CtrlType)
            {
            case TEXT:
                lb_picture->setText(pictureresourceslist[pageindex][0]);
                break;
            case IMAGE:
                mv_media->stop();
                mv_media->setFileName(pictureresourceslist[pageindex][0]);
                mv_media->start();
                //lb_picture->setPixmap(QPixmap(pictureresourceslist[pageindex][0]));
                break;
            default:
                break;
            }
            initOpacityWithTimer();
        }
    }
}

//初始化画面效果,并打开计时器开启切换效果
void SwitchPicture::initOpacityWithTimer()
{
    switchturn = 0;//示意图标号
    opacity = 1.0;//透明度值
    switchcase = 0;//淡入淡出中间状态标志
    setPictureOpacity();
    if (pictureresourceslist.length() > pageindex && pictureresourceslist[pageindex].length() > 1)
    {
        tm_switch->start(staymsec);
    }
}

//切换响应事件
void SwitchPicture::on_pictureswitching()
{
    if (pictureresourceslist.length() > pageindex)
    {
        if (pictureresourceslist[pageindex].length() - switchturn > 1)
        {
            switchToNext(switchturn + 1);
        }
        else
        {
            switchToNext(0);
        }
    }
}

//切换到对应图片与文字
void SwitchPicture::switchToNext(long nextturn)
{
    if (opacity > 0.0)
    {
        tm_switch->setInterval(switchmsec);
        if (switchcase == 0)
        {
            opacity -= opacityinterval;
        }
        else
        {
            opacity += opacityinterval;
        }
        setPictureOpacity();
        if (opacity == 1.0)
        {
            switchturn = nextturn;
            switchcase = 0;
            tm_switch->setInterval(staymsec);
        }
    }
    else
    {
        QString resstr = pictureresourceslist[pageindex][nextturn];
        switch(CtrlType)
        {
        case TEXT:
            lb_picture->setText(resstr);
            break;
        case IMAGE:
            mv_media->stop();
            mv_media->setFileName(resstr);
            mv_media->start();
            //lb_picture->setPixmap(QPixmap(resstr));
            break;
        default:
            break;
        }
        switchcase = 1;
        if (movein == NONE)//防止移出后没有移入,图片显示不出来
        {
            lb_picture->setGeometry(QRect(0, 0, lb_picture->width(), lb_picture->height()));
        }
        opacity += opacityinterval;
        setPictureOpacity();
    }
}

//设置透明度与位移效果
void SwitchPicture::setPictureOpacity()
{
    //*淡入淡出效果*************************************************//
    pictureeffect->setOpacity(opacity);
    lb_picture->setGraphicsEffect(pictureeffect);
    //*移入移出效果*************************************************//
    if (switchcase == 0)
    {//opacity:1->0
        switch(moveout)
        {
        case NONE:
            break;
        case LEFTTORIGHT:
            lb_picture->setGeometry(QRect(lb_picture->width() * (1.0 - opacity), 0, lb_picture->width(), lb_picture->height()));
            break;
        case RIGHTTOLEFT:
            lb_picture->setGeometry(QRect(lb_picture->width() * (opacity - 1.0), 0, lb_picture->width(), lb_picture->height()));
            break;
        case UPTODOWN:
            lb_picture->setGeometry(QRect(0, lb_picture->height() * (1.0 - opacity), lb_picture->width(), lb_picture->height()));
            break;
        case DOWNTOUP:
            lb_picture->setGeometry(QRect(0, lb_picture->height() * (opacity - 1.0), lb_picture->width(), lb_picture->height()));
            break;
        default:
            break;
        }
    }
    else
    {//opacity:0->1
        switch(movein)
        {
        case NONE:
            break;
        case LEFTTORIGHT:
            lb_picture->setGeometry(QRect(lb_picture->width() * (opacity - 1.0), 0, lb_picture->width(), lb_picture->height()));
            break;
        case RIGHTTOLEFT:
            lb_picture->setGeometry(QRect(lb_picture->width() * (1.0 - opacity), 0, lb_picture->width(), lb_picture->height()));
            break;
        case UPTODOWN:
            lb_picture->setGeometry(QRect(0, lb_picture->height() * (opacity - 1.0), lb_picture->width(), lb_picture->height()));
            break;
        case DOWNTOUP:
            lb_picture->setGeometry(QRect(0, lb_picture->height() * (1.0 - opacity), lb_picture->width(), lb_picture->height()));
            break;
        default:
            break;
        }
    }
}

void SwitchPicture::setOpacityInterval(double opacityinterval)//设置透明度渐变粒度
{
    this->opacityinterval = opacityinterval;
}

void SwitchPicture::setSwitchMsec(long switchmsec, long staymsec)//设置渐变计时器时间与停留时间
{
    this->switchmsec = switchmsec;
    this->staymsec = staymsec;
}

void SwitchPicture::addPictureResources(QList<QString> reslist)//添加播放图集
{
    this->pictureresourceslist.push_back(reslist);
}

void SwitchPicture::clearPictureResources()//清空播放图集
{
    this->pictureresourceslist.clear();
}

void SwitchPicture::setTextStyle(QFont font, QPalette palette)//设置文字显示时的字体与颜色
{
    lb_picture->setFont(font);
    lb_picture->setPalette(palette);
}

void SwitchPicture::setMoveWay(MOVEWAY movein, MOVEWAY moveout)//设置移入移出的方向
{
    this->movein = movein;
    this->moveout = moveout;
}

void SwitchPicture::resizeEvent(QResizeEvent *event)
{
    lb_picture->setGeometry(QRect(0,0,this->width(),this->height()));
    this->QWidget::resizeEvent(event);
}

这里用QMovie是为了兼容gif动态图片,也可以根据所需,修改成其它Qwidget的子类;比如对话框、登陆框等等;

你可能感兴趣的:(qt,淡入淡出,渐变效果,Qt实现平移效果,Qt实现淡入淡出效果)