Qt實(shí)現(xiàn)界面滑動(dòng)切換效果的思路詳解
一、Qt實(shí)現(xiàn)界面滑動(dòng)切換效果
效果如下圖,滑動(dòng)效果移動(dòng)上下屏幕。

二、 設(shè)計(jì)思路
利用QStackWidget將頁(yè)面存儲(chǔ)起來,因?yàn)轫?yè)面比較少,因此我直接將所有的頁(yè)面存儲(chǔ)在QStachWidget中,如果頁(yè)面相對(duì)較多,可以使用使用使渲染的方式。
然后使用show函數(shù)同時(shí)展示兩個(gè)頁(yè)面的內(nèi)容,這個(gè)很重要,如果使用setCurrentIndex只會(huì)展示一個(gè)界面,這樣不會(huì)出現(xiàn)兩個(gè)界面同時(shí)存在的情況。
使用QPropertyAnimation以及QParallelAnimationGroup來設(shè)置界面切換動(dòng)畫。
當(dāng)頁(yè)面左移動(dòng)時(shí),將原始界面移除屏幕到左邊,將當(dāng)前界面從右邊移動(dòng)至現(xiàn)在界面位置。
當(dāng)頁(yè)面右移動(dòng)時(shí),將原始界面移除屏幕到右邊,將當(dāng)前界面從左邊移動(dòng)至屏幕展示位置
三、主要函數(shù)講解
QPropertyAnimation:動(dòng)畫類,如果僅控制一個(gè)界面的動(dòng)畫可以直接設(shè)置動(dòng)畫效果后,start函數(shù)啟動(dòng)動(dòng)畫效果。
QParallelAnimationGroup:動(dòng)畫組類,控制一組動(dòng)畫同時(shí)運(yùn)行,我們這里控制了兩個(gè)界面因此需要使用QParallelAnimationGroup來控制兩個(gè)界面的動(dòng)畫。
QStackedWidget:用于存儲(chǔ)多個(gè)界面,當(dāng)界面需要展示的時(shí)候可以通過setCurrentIndex展示當(dāng)前頁(yè)面。
四、源代碼解析
4、1 初始化界面
在QStatchWidget中添加多個(gè)界面。因?yàn)檫@是游戲界面初始化,每一頁(yè)有25題,一共有515道題目,翻頁(yè)的總數(shù)等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("上一個(gè)", this))
, m_ptrBtnNext(new QPushButton("下一個(gè)", 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);
}
// 設(shè)置當(dāng)前展示的界面索引。
m_ptrStackWidget->setCurrentIndex(0);
// 添加上一頁(yè)按鈕
m_ptrLayoutMain->addWidget(m_ptrBtnPre);
// 添加展示的界面
m_ptrLayoutMain->addWidget(m_ptrStackWidget);
// 添加下一頁(yè)按鈕
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 上一頁(yè)滑動(dòng)效果
獲取展示界面的寬度以及高度,下移動(dòng)界面的時(shí)候需要使用。
m_bDonghua:記錄當(dāng)前是否在動(dòng)畫效果中,如果在動(dòng)畫效果中不進(jìn)行翻頁(yè)(如果不設(shè)置,在快速切換的時(shí)候會(huì)出現(xiàn)重影)
m_ptrStackWidget->setCurrentIndex(PreIndex);
m_ptrStackWidget->widget(currentIndex)->show();animation1:設(shè)置當(dāng)前頁(yè)(未切換前)面頁(yè)面的動(dòng)畫效果,你可以看到startValue和endValue,是從原始屏幕位置移除屏幕外。
animation2:設(shè)置即將切換到界面的動(dòng)畫效果,你可以看到startValue和endValue,是從屏幕外位置移除屏幕正中間。
當(dāng)界面的動(dòng)畫同時(shí)執(zhí)行的時(shí)候就出現(xiàn)滑動(dòng)效果。
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 下一頁(yè)滑動(dòng)效果
獲取展示界面的寬度以及高度,下移動(dòng)界面的時(shí)候需要使用。
m_bDonghua:記錄當(dāng)前是否在動(dòng)畫效果中,如果在動(dòng)畫效果中不進(jìn)行翻頁(yè)(如果不設(shè)置,在快速切換的時(shí)候會(huì)出現(xiàn)重影)
m_ptrStackWidget->setCurrentIndex(NextIndex);
m_ptrStackWidget->widget(currentIndex)->show();animation1:設(shè)置當(dāng)前頁(yè)(未切換前)面頁(yè)面的動(dòng)畫效果,你可以看到startValue和endValue,是從原始屏幕位置移除屏幕外。
animation2:設(shè)置即將切換到界面的動(dòng)畫效果,你可以看到startValue和endValue,是從屏幕外位置移除屏幕正中間。
當(dāng)界面的動(dòng)畫同時(shí)執(zhí)行的時(shí)候就出現(xiàn)滑動(dòng)效果。
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 動(dòng)畫結(jié)束處理
動(dòng)畫結(jié)束后需要將上一界面進(jìn)行隱藏,在切換頁(yè)面的時(shí)候已經(jīng)將上一頁(yè)面的指針保存發(fā)送過來了。
group->setProperty(
"widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));因此在動(dòng)畫結(jié)束時(shí),獲取上一頁(yè)面的指針,然后再修改其隱藏狀態(tài)即可。
void LevelMainWidget::onAnimationFinished()
{
QParallelAnimationGroup* group = (QParallelAnimationGroup*)sender();
QWidget* widget = group->property("widget").value<QWidget*>();
if (nullptr != widget) {
widget->hide();
}
m_bDonghua = false;
}五、源碼地址
源碼地址: 啊淵 / QT博客案例
到此這篇關(guān)于Qt實(shí)現(xiàn)界面滑動(dòng)切換效果的文章就介紹到這了,更多相關(guān)Qt界面滑動(dòng)切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Qt+OpenCV實(shí)現(xiàn)圖像灰度化像素
在圖像處理領(lǐng)域,OpenCV是一款強(qiáng)大而廣泛應(yīng)用的開源庫(kù),能夠提供豐富的圖像處理和計(jì)算機(jī)視覺功能,本文將介紹如何利用Qt?編輯器調(diào)用OpenCV庫(kù)對(duì)照片進(jìn)行換底色處理,實(shí)現(xiàn)更加獨(dú)特和吸引人的效果2023-11-11
Qt5 串口類QSerialPort的實(shí)現(xiàn)
在Qt5以上提供了QtSerialPort模塊,方便編程人員快速的開發(fā)應(yīng)用串口的應(yīng)用程序。本文主要介紹了Qt5 串口類QSerialPort的實(shí)現(xiàn),,感興趣的可以了解一下2022-05-05
C語(yǔ)言實(shí)現(xiàn)銷售管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)銷售管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++使用cuBLAS加速矩陣乘法運(yùn)算的實(shí)現(xiàn)代碼
這篇文章主要介紹了C++使用cuBLAS加速矩陣乘法運(yùn)算,將cuBLAS庫(kù)的乘法運(yùn)算進(jìn)行了封裝,方便了算法調(diào)用,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2021-09-09

