1. 程式人生 > >Qt實現移入移出與淡入淡出效果

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的子類;比如對話方塊、登陸框等等;