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

一、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界面滑動切換內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: