首頁 > 軟體

Qt實現介面滑動切換效果的思路詳解

2022-07-05 18:01:45

一、Qt實現介面滑動切換效果

效果如下圖,滑動效果移動上下螢幕。

二、 設計思路

利用QStackWidget將頁面儲存起來,因為頁面比較少,因此我直接將所有的頁面儲存在QStachWidget中,如果頁面相對較多,可以使用使用使渲染的方式。

然後使用show函數同時展示兩個頁面的內容,這個很重要,如果使用setCurrentIndex只會展示一個介面,這樣不會出現兩個介面同時存在的情況。

使用QPropertyAnimation以及QParallelAnimationGroup來設定介面切換動畫。

當頁面左移動時,將原始介面移除螢幕到左邊,將當前介面從右邊移動至現在介面位置。

當頁面右移動時,將原始介面移除螢幕到右邊,將當前介面從左邊移動至螢幕展示位置

三、主要函數講解

QPropertyAnimation:動畫類,如果僅控制一個介面的動畫可以直接設定動畫效果後,start函數啟動動畫效果。

QParallelAnimationGroup:動畫組類,控制一組動畫同時執行,我們這裡控制了兩個介面因此需要使用QParallelAnimationGroup來控制兩個介面的動畫。

QStackedWidget:用於儲存多個介面,當介面需要展示的時候可以通過setCurrentIndex展示當前頁面。

四、原始碼解析

4、1 初始化介面

在QStatchWidget中新增多個介面。因為這是遊戲介面初始化,每一頁有25題,一共有515道題目,翻頁的總數等int(515/25).

#define MAX_NUM 515
LevelMainWidget::LevelMainWidget(QWidget* parent)
    : QWidget(parent)
 
    , m_ptrStackWidget(new QStackedWidget(this))
    , m_ptrLayoutMain(new QHBoxLayout)
    , m_ptrBtnPre(new QPushButton("上一個", this))
    , m_ptrBtnNext(new QPushButton("下一個", this))
    , m_bDonghua(false)
 
{
    // 新增介面
    for (int i = 0; i < 515; i += 25) {
        int start = i + 1;
        int end = i + 25;
        if (end > 515) {
            end = 515;
        }
        LevelWidget* lvlWidget = new LevelWidget(start, end);
        m_listLevelWidget.append(lvlWidget);
        m_ptrStackWidget->addWidget(lvlWidget);
        connect(lvlWidget, &LevelWidget::sigBtnClick, this,
                &LevelMainWidget::slotBtnLevel);
    }
    // 設定當前展示的介面索引。
    m_ptrStackWidget->setCurrentIndex(0);
    // 新增上一頁按鈕
    m_ptrLayoutMain->addWidget(m_ptrBtnPre);
    // 新增展示的介面
    m_ptrLayoutMain->addWidget(m_ptrStackWidget);
    // 新增下一頁按鈕
    m_ptrLayoutMain->addWidget(m_ptrBtnNext);
    setFixedSize(500, 500);
    setLayout(m_ptrLayoutMain);
    initConnect();
}
void LevelMainWidget::initConnect()
{
    connect(m_ptrBtnPre, SIGNAL(clicked()), this, SLOT(slotBtnPre()));
    connect(m_ptrBtnNext, SIGNAL(clicked()), this, SLOT(slotBtnNext()));
}

4、2 上一頁滑動效果

獲取展示介面的寬度以及高度,下移動介面的時候需要使用。

m_bDonghua:記錄當前是否在動畫效果中,如果在動畫效果中不進行翻頁(如果不設定,在快速切換的時候會出現重影)

    m_ptrStackWidget->setCurrentIndex(PreIndex);
    m_ptrStackWidget->widget(currentIndex)->show();

animation1:設定當前頁(未切換前)面頁面的動畫效果,你可以看到startValue和endValue,是從原始螢幕位置移除螢幕外。

animation2:設定即將切換到介面的動畫效果,你可以看到startValue和endValue,是從螢幕外位置移除螢幕正中間。

當介面的動畫同時執行的時候就出現滑動效果。

void LevelMainWidget::slotBtnPre()
{
    if (m_bDonghua) {
        return;
    }
    m_bDonghua = true;
    int currentIndex = m_ptrStackWidget->currentIndex();
    int windowWidth = m_ptrStackWidget->widget(currentIndex)->width();
    int windowHieght = m_ptrStackWidget->widget(currentIndex)->height();
    int PreIndex = currentIndex - 1;
    if (currentIndex == 0) {
        return;
    }
    m_ptrStackWidget->setCurrentIndex(PreIndex);
    m_ptrStackWidget->widget(currentIndex)->show();
    QPropertyAnimation* animation1;
    QPropertyAnimation* animation2;
    QParallelAnimationGroup* group = new QParallelAnimationGroup;
    animation1 = new QPropertyAnimation(m_ptrStackWidget->widget(currentIndex),
                                        "geometry");
    animation1->setDuration(500);
    animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
    animation1->setEndValue(QRect(windowWidth, 0, windowWidth, windowHieght));
 
    animation2 =
        new QPropertyAnimation(m_ptrStackWidget->widget(PreIndex), "geometry");
    animation2->setDuration(500);
    animation2->setStartValue(
        QRect(-windowWidth, 0, windowWidth, windowHieght));
    animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));
 
    group->addAnimation(animation1);
    group->addAnimation(animation2);
    group->start();
    group->setProperty(
        "widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));
    connect(group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
}

4、3  下一頁滑動效果

獲取展示介面的寬度以及高度,下移動介面的時候需要使用。

m_bDonghua:記錄當前是否在動畫效果中,如果在動畫效果中不進行翻頁(如果不設定,在快速切換的時候會出現重影)

    m_ptrStackWidget->setCurrentIndex(NextIndex);
    m_ptrStackWidget->widget(currentIndex)->show();

animation1:設定當前頁(未切換前)面頁面的動畫效果,你可以看到startValue和endValue,是從原始螢幕位置移除螢幕外。

animation2:設定即將切換到介面的動畫效果,你可以看到startValue和endValue,是從螢幕外位置移除螢幕正中間。

當介面的動畫同時執行的時候就出現滑動效果。

void LevelMainWidget::slotBtnNext()
{
    if (m_bDonghua) {
        return;
    }
    m_bDonghua = true;
    int currentIndex = m_ptrStackWidget->currentIndex();
    int windowWidth = m_ptrStackWidget->widget(currentIndex)->width();
    int windowHieght = m_ptrStackWidget->widget(currentIndex)->height();
    int NextIndex = currentIndex + 1;
    if (currentIndex >= m_ptrStackWidget->count()) {
        return;
    }
    m_ptrStackWidget->setCurrentIndex(NextIndex);
    m_ptrStackWidget->widget(currentIndex)->show();
    QPropertyAnimation* animation1;
    QPropertyAnimation* animation2;
    QParallelAnimationGroup* group = new QParallelAnimationGroup;
    animation1 = new QPropertyAnimation(m_ptrStackWidget->widget(currentIndex),
                                        "geometry");
    animation1->setDuration(500);
    animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
    animation1->setEndValue(QRect(-windowWidth, 0, windowWidth, windowHieght));
 
    animation2 =
        new QPropertyAnimation(m_ptrStackWidget->widget(NextIndex), "geometry");
    animation2->setDuration(500);
    animation2->setStartValue(QRect(windowWidth, 0, windowWidth, windowHieght));
    animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));
 
    group->addAnimation(animation1);
    group->addAnimation(animation2);
    group->start();
    group->setProperty(
        "widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));
    connect(group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
}

4、4 動畫結束處理

動畫結束後需要將上一介面進行隱藏,在切換頁面的時候已經將上一頁面的指標儲存傳送過來了。

 group->setProperty(
        "widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));

因此在動畫結束時,獲取上一頁面的指標,然後再修改其隱藏狀態即可。 

void LevelMainWidget::onAnimationFinished()
{
    QParallelAnimationGroup* group = (QParallelAnimationGroup*)sender();
    QWidget* widget = group->property("widget").value<QWidget*>();
    if (nullptr != widget) {
        widget->hide();
    }
    m_bDonghua = false;
}

五、原始碼地址 

原始碼地址: 啊淵 / QT部落格案例

到此這篇關於Qt實現介面滑動切換效果的文章就介紹到這了,更多相關Qt介面滑動切換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com