1. 程式人生 > >【第五篇】Qt學習與使用---自定義的圖片輪播類(滾動播放圖片)

【第五篇】Qt學習與使用---自定義的圖片輪播類(滾動播放圖片)

1、目標

編寫一個類,可以展示幾張圖片。類似於現在流行的視訊播放器的首頁中出現的滾動展示的控制元件。

 

2、 具體要求

(1)一次性展示三張圖片,左中右。中間的圖片至於頂部,旁邊的圖片被覆蓋,只露出一部分。

(2) 切換圖片的時候,呈現動態效果,需要有一個移動的過程。

(3)有自動輪播和手動切換的功能。

3、程式設計思路

(1)需要用到兩個定時器,一個做 自動輪播定時,一個做移動過程定時。

(2)只考慮超過三張圖片的情況(少於三張圖片不使用該程式),需要使用容器存放圖片地址。

4、直接看程式碼

檔案:mywidget.h檔案

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QLabel>
#include <QVector>
#include <QTimer>
#include <QPushButton>

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    int flag_ING=0;         //正在移動的標記(起到自鎖的功能)
    int flag_leftright=1;   //控制圖片移動的方向(向左為正,next)
    int nowchoose=0;        //記錄圖片編號
    int X1=0,X2=0,X3=0,YYY=0,DX=0;//三張圖片的固定位置
    int thisWidth;              //屏寬
    int thisHeight;             //屏高
    QWidget* W1,*W2,*W3;        //三張放圖片的面板
    QTimer* timer;              //動作定時器
    QTimer* OneTimeTimer;       //輪播定時器
    explicit MyWidget(QWidget *parent = 0, int WWW=0, int HHH=0);
    QVector<QString> Vector_pics;//圖片容器
    void init_Things();
    void init_btn();
    QPushButton* btn_next;
    QPushButton* btn_before;
    void init_lb();
    QLabel* lb1;                //圖片載體
    QLabel* lb2;
    QLabel* lb3;
    QLabel* lb_backgroundcolor;//控制元件背景色控制
signals:

public slots:
    void slot_timerout();
    void slot_timeroutOne();
    void slot_next();
    void slot_before();
};

#endif // MYWIDGET_H

檔案:mywidget.cpp檔案

#include "mywidget.h"
#include <QDebug>
#include <QHBoxLayout>
#define Kshine 1.5 //大小(1/kshine* 螢幕)
#define KshineSpeed 3 //移動速度
MyWidget::MyWidget(QWidget *parent, int WWW, int HHH) : QWidget(parent)
{

    if(WWW&&HHH)
    {
        //建立時指定大小
        thisWidth=WWW;
        thisHeight=HHH;

    }
    else
    {
        //預設子頁面大小
        thisWidth=1920;
        thisHeight=1080;
        this->setStyleSheet("background-color:yellow;");
    }
    this->setFixedSize(thisWidth,thisHeight/Kshine+thisHeight*Kshine/36+80);
    this->setAutoFillBackground(true);
    lb_backgroundcolor =new QLabel(this);
    lb_backgroundcolor->setFixedSize(thisWidth,thisHeight/Kshine+thisHeight*Kshine/36+80);
    lb_backgroundcolor->setStyleSheet("background-color:rgb(50,50,50);");
    qDebug()<<"頁面:概覽  尺寸:"<<width()<<height();

    OneTimeTimer = new QTimer(this);
    OneTimeTimer->setInterval(3000);
    connect(OneTimeTimer,SIGNAL(timeout()),this,SLOT(slot_timeroutOne()));
    OneTimeTimer->start();
    timer = new QTimer(this);
    timer->setInterval(1);
    connect(timer,SIGNAL(timeout()),this,SLOT(slot_timerout()));
    Vector_pics.append(":/picture/test/1.png");
    Vector_pics.append(":/picture/test/2.png");
    Vector_pics.append(":/picture/test/3.png");
    Vector_pics.append(":/picture/test/4.png");
    Vector_pics.append(":/picture/test/5.png");
    Vector_pics.append(":/picture/login/loginbackground.jpg");
    init_Things();
    init_lb();
    init_btn();
    show();
}

void MyWidget::init_Things()
{
    nowchoose=0;
    X1=thisWidth*(Kshine-2)/Kshine/2;
    X2=thisWidth*(Kshine-1)/Kshine/2;
    X3=thisWidth/2;
    qDebug()<<X1<<X2<<X3;
    YYY=thisHeight*Kshine/36;

    W1 =new QWidget(this);
    W2 =new QWidget(this);
    W3 =new QWidget(this);
    W1->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);
    W2->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);
    W3->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);
    W1->setStyleSheet("background-color:red;");
    W2->setStyleSheet("background-color:blue;");
    W3->setStyleSheet("background-color:green;");
    W1->move(X1,YYY);W2->move(X2,YYY);W3->move(X3,YYY);
    W2->raise();
    //    Vector_pics.append("123");
    //    Vector_pics.append("123");
    //    Vector_pics.append("123");
    //    Vector_pics.append("123");
    //    Vector_pics.append("123");

}

void MyWidget::init_btn()
{
    btn_next =new QPushButton(this);btn_next->setText("=>");
    connect(btn_next,SIGNAL(clicked(bool)),this,SLOT(slot_next()));
    btn_before =new QPushButton(this);btn_before->setText("<=");
    connect(btn_before,SIGNAL(clicked(bool)),this,SLOT(slot_before()));
    QHBoxLayout* ly_H_btn=new QHBoxLayout();
    ly_H_btn->addStretch();
    ly_H_btn->addWidget(btn_before);
    ly_H_btn->addSpacing(30);
    ly_H_btn->addWidget(btn_next);
    ly_H_btn->addStretch();
    ly_H_btn->setGeometry(QRect(0,YYY+thisHeight/Kshine+20,thisWidth,40));
}

void MyWidget::init_lb()
{

    lb1 = new QLabel(W1);
    lb2 = new QLabel(W2);
    lb3 = new QLabel(W3);
    lb1->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);
    lb2->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);
    lb3->setFixedSize(thisWidth/Kshine,thisHeight/Kshine);

    QPixmap pixmap1,pixmap2,pixmap3;
    pixmap1.load(Vector_pics.last());qDebug()<<Vector_pics.last();
    pixmap1.scaled(lb1->size(), Qt::IgnoreAspectRatio);
    lb1->setScaledContents(true);
    lb1->setPixmap(pixmap1);

    pixmap2.load(Vector_pics.first());qDebug()<<Vector_pics.first();
    pixmap2.scaled(lb2->size(), Qt::IgnoreAspectRatio);
    lb2->setScaledContents(true);
    lb2->setPixmap(pixmap2);

    pixmap3.load(Vector_pics[1]);qDebug()<<Vector_pics[1];
    pixmap3.scaled(lb3->size(), Qt::IgnoreAspectRatio);
    lb3->setScaledContents(true);
    lb3->setPixmap(pixmap3);
}

void MyWidget::slot_timerout()
{
    if(flag_leftright)
    {
        //左移
        if(W2->x()>X1)//先移動
        {
            W2->move(W2->x()-KshineSpeed,YYY);
            //W1->move(W1->x()+2*KshineSpeed,YYY);
            if(W2->x() <= X1)
            {
                W3->raise();
                QPixmap pixmap1;
                int num =(nowchoose+2)%Vector_pics.length();
                pixmap1.load(Vector_pics[num]);
                pixmap1.scaled(lb1->size(), Qt::IgnoreAspectRatio);
                lb1->setPixmap(pixmap1);
                W1->move(X3,YYY);//直接過來
            }
        }
        if(W2->x()  <=  X1  &&   W3->x()    >   X2)
        {
            W3->move(W3->x()-KshineSpeed,YYY);
            if(W3->x() <= X2)
            {
                timer->stop();
                QWidget* temp=W1;
                W1=W2;
                W2=W3;
                W3=temp;
                QLabel* tb=lb1;
                lb1=lb2;
                lb2=lb3;
                lb3=tb;
                flag_ING=0;
            }
        }
    }
    else
    {
        //右移
        if(W2->x()<X3)//中間先移動
        {
            W2->move(W2->x()+KshineSpeed,YYY);
            //W3->move(W3->x()-2*KshineSpeed,YYY);
            if(W2->x() >= X3)
            {
                W1->raise();
                QPixmap pixmap3;
                int num =(nowchoose-2)%Vector_pics.length();
                if(num<0)num+=Vector_pics.length();
                pixmap3.load(Vector_pics[num]);
                pixmap3.scaled(lb3->size(), Qt::IgnoreAspectRatio);
                lb3->setPixmap(pixmap3);
                W3->move(X1,YYY);//直接過來
            }
        }
        if(W2->x()>=X3  &&   W1->x()    <   X2)//2向右移動完,1未移動完
        {
            W1->move(W1->x()+KshineSpeed,YYY);
            if(W1->x() >= X2)
            {
                timer->stop();
                QWidget* temp=W3;
                W3=W2;
                W2=W1;
                W1=temp;
                QLabel* tb=lb3;
                lb3=lb2;
                lb2=lb1;
                lb1=tb;
                flag_ING=0;
            }
        }




    }
}

void MyWidget::slot_timeroutOne()
{
    //左移
    if(flag_ING)return;
    flag_leftright=1;
    nowchoose++;
    if(nowchoose>=Vector_pics.length())nowchoose=0;
    W1->lower();
    lb_backgroundcolor->lower();
    timer->start();
    flag_ING=1;
}

void MyWidget::slot_next()
{
    //左移
    OneTimeTimer->stop();
    if(flag_ING)return;
    flag_leftright=1;
    nowchoose++;
    if(nowchoose>=Vector_pics.length())nowchoose=0;
    W1->lower();
    lb_backgroundcolor->lower();
    timer->start();
    flag_ING=1;
}

void MyWidget::slot_before()
{
    //右移
    OneTimeTimer->stop();
    if(flag_ING)return;
    flag_leftright=0;
    nowchoose--;
    if(nowchoose<0)nowchoose=Vector_pics.length()-1;
    W3->lower();
    lb_backgroundcolor->lower();
    timer->start();
    flag_ING=1;
}

 

5、效果展示

6、其他

歡迎提問和交流。另外如果想在 左右兩邊的圖片上增加點選切換的效果,需要在控制元件的外面新增。通過訊號槽的機制控制。