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!
推薦閱讀:
- 詳解Qt中QStackedWidget控件的使用
- Qt重寫QStackedWidget模擬實現home界面滑動效果
- Qt編寫自定義控件實現抽獎轉盤
- Qt中樹形控件Tree Widget的使用方法匯總
- Qt實現圖形裁減