当前位置: 首页 > news >正文

QT实现滑动页面组件,多页面动态切换

        这篇文章主要介绍了Qt实现界面滑动切换效果,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下。

一、简述

          一个基于Qt的动态滑动页面组件。 

二、 设计思路

1、自定义StackWidget类,继承自QWidget,实现一个堆叠的窗口组件,可以在其中放置多个子窗口,只显示当前活动窗口。

2、使用QPropertyAnimation来设置界面切换动画。

三、效果 

四、核心代码  
1、头文件astackwidget.h
#include <QWidget>class QPropertyAnimation;
class AStackWidget : public QWidget
{Q_OBJECT
public:AStackWidget(QWidget *parent);~AStackWidget();public:int count() const;int currentIndex() const;int addWidget(QWidget *widget);int indexOf(QWidget *widget) const;int insertWidget(int index, QWidget *widget);QWidget *currentWidget() const;QWidget *widget(int index) const;void removeWidget(QWidget *widget);void setDuration(int duration);signals:void currentChanged(int index);void widgetRemoved(int index);public slots:void setCurrentIndex(int index);void setCurrentWidget(QWidget *widget);private slots:void onValueChanged(const QVariant &);void onMoveFinished();private:void moveAnimationStart();void setWidgetsVisible();protected:void resizeEvent(QResizeEvent *event);private:int m_offset;int m_curIndex;int m_lastIndex;int m_duration;QPropertyAnimation *m_moveAnimation;QList<QWidget *> m_widgetLst;
};
2、实现代码astackwidget.cpp
#include "astackwidget.h"
#include <QPropertyAnimation>AStackWidget::AStackWidget(QWidget *parent): QWidget(parent)
{m_offset = 0;m_curIndex = 0;m_lastIndex = 0;m_duration = 500;m_moveAnimation = new QPropertyAnimation(this, "");m_moveAnimation->setDuration(m_duration);connect(m_moveAnimation, &QPropertyAnimation::valueChanged, this, &AStackWidget::onValueChanged);connect(m_moveAnimation, &QPropertyAnimation::finished, this, &AStackWidget::onMoveFinished);
}AStackWidget::~AStackWidget()
{}int AStackWidget::count() const
{return m_widgetLst.size();
}int AStackWidget::currentIndex() const
{return m_curIndex;
}void AStackWidget::setDuration(int duration)
{m_duration = duration;
}int AStackWidget::addWidget(QWidget * widget)
{int index = indexOf(widget);if (index >= 0){return index;}widget->setParent(this);m_widgetLst.append(widget);return count() - 1;
}int AStackWidget::indexOf(QWidget * widget) const
{return m_widgetLst.indexOf(widget);
}int AStackWidget::insertWidget(int index, QWidget * widget)
{int curindex = indexOf(widget);if (curindex >= 0) {return curindex;}widget->setParent(this);m_widgetLst.insert(index, widget);return index;
}QWidget * AStackWidget::currentWidget() const
{if (m_curIndex >= 0 && m_curIndex < count()){return m_widgetLst.at(m_curIndex);}return 0;
}QWidget * AStackWidget::widget(int index) const
{if (index >= 0 && index < count()) {return m_widgetLst.at(index);}return 0;
}void AStackWidget::removeWidget(QWidget * widget)
{int index = indexOf(widget);if (index >= 0) {m_widgetLst.removeAll(widget);emit widgetRemoved(index);}
}void AStackWidget::setCurrentWidget(QWidget * widget)
{int index = indexOf(widget);if (index >= 0 && m_curIndex != index) {setCurrentIndex(index);}
}void AStackWidget::setCurrentIndex(int index)
{if (index >= 0 && m_curIndex != index) {m_lastIndex = m_curIndex;m_curIndex = index;	moveAnimationStart();emit currentChanged(index);}
}void AStackWidget::resizeEvent(QResizeEvent *event)
{QWidget::resizeEvent(event);int size = count();for (int i = 0; i < size; i++) {m_widgetLst.at(i)->resize(this->width(), this->height());}if (m_moveAnimation->state() == QAbstractAnimation::Running) {moveAnimationStart();}else {setWidgetsVisible();onValueChanged(0);}
}void AStackWidget::onValueChanged(const QVariant &value)
{m_offset = value.toInt();m_widgetLst.at(m_curIndex)->move(m_offset, 0);if (m_curIndex > m_lastIndex) {m_widgetLst.at(m_lastIndex)->move(m_offset - this->width(), 0);} else if (m_curIndex < m_lastIndex){m_widgetLst.at(m_lastIndex)->move(this->width() + m_offset, 0);}
}void AStackWidget::moveAnimationStart()
{m_moveAnimation->stop();setWidgetsVisible();int startOffset = m_offset;if (m_curIndex > m_lastIndex) {if (startOffset == 0) startOffset = this->width();else startOffset = this->width() - qAbs(startOffset);}else {if (startOffset == 0) startOffset = -this->width();else startOffset = qAbs(startOffset) - this->width();}m_moveAnimation->setDuration(qAbs(startOffset) * m_duration / this->width());m_moveAnimation->setStartValue(startOffset);m_moveAnimation->setEndValue(0);m_moveAnimation->start();
}void AStackWidget::setWidgetsVisible()
{int size = count();for (int i = 0; i < size; i++) {if (m_lastIndex == i || m_curIndex == i)m_widgetLst.at(i)->setVisible(true);else {m_widgetLst.at(i)->setVisible(false);}}
}void AStackWidget::onMoveFinished()
{//可在此添加动画结束后处理代码
}

QPropertyAnimation:动画类,如果仅控制一个界面的动画可以直接设置动画效果后,start函数启动动画效果。

StackedWidget:用于存储多个界面,当界面需要展示的时候可以通过setCurrentIndex展示当前页面。

五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中实现滑动页面组件和多页面动态切换:

 1、实现步骤
  1. 在应用程序中创建 StackedWidget的对象
  2. 将多个子组件在容器对象中布局
  3. 将容器对象加入StackedWidget中生成新的页面
  4. 通过StackedWidget的setCurrentIndex切换页面。
 2、ui设计 frmastackwidget.ui

3、使用代码
#include "FrmAStackWidget.h"
#include <QButtonGroup>
#include <QLabel>FrmAStackWidget::FrmAStackWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);QList<QString> colorlst;colorlst << "#1abc9c";colorlst << "#2ecc71";colorlst << "#3498db";colorlst << "#9b59b6";colorlst << "#e74c3c";QList<QPushButton *> btnlst;btnlst << ui.pushButton_1;btnlst << ui.pushButton_2;btnlst << ui.pushButton_3;btnlst << ui.pushButton_4;btnlst << ui.pushButton_5;QButtonGroup *btnGroup = new QButtonGroup(this);connect(btnGroup, SIGNAL(buttonClicked(int)), ui.aStackwidget, SLOT(setCurrentIndex(int)));for (int i = 0; i < 5; i++) {QLabel *label = new QLabel(ui.aStackwidget);label->setStyleSheet(QString("background-color:%1;color:#ffffff;").arg(colorlst.at(i)));label->setText(QString::number(i + 1));label->setAlignment(Qt::AlignCenter);int index = ui.aStackwidget->addWidget(label);btnGroup->addButton(btnlst.at(i), index);}
}

        这个示例只是一个基本的实现,实际应用中可能需要更复杂的逻辑来处理动画效果。 望大家看完这篇文章后可以实现自己的翻页动画效果。

六、源代码下载
http://www.lryc.cn/news/401688.html

相关文章:

  • 使用Python-docx库创建Word文档
  • C# 设计一个可变长度的数据通信协议编码和解码代码。
  • 【MATLAB库函数系列】MATLAB库函数pwelch之功率谱估计的详解及实现
  • 科技出海|百分点科技智慧政务解决方案亮相非洲展会
  • Prometheus 云原生 - Prometheus 数据模型、Metrics 指标类型、Exporter 相关
  • Qt窗口程序整理汇总
  • 简单实现一个本地ChatGPT web服务(langchain框架)
  • Elasticsearch-多边形范围查询(8.x)
  • Kotlin Misk Web框架
  • 【设计模式之美】【建造型】工厂模式:通过面向接口编程思路,串起业务流程
  • AI算法19-偏最小二乘法回归算法Partial Least Squares Regression | PLS
  • live555关于RTSP协议交互流程
  • Centos7 安装私有 Gitlab
  • 浅谈数学模型在UGC/AIGC游戏数值配置调参中的应用(AI智能体)
  • 第T5周:使用TensorFlow实现运动鞋品牌识别
  • 网络编程学习之tcp
  • 前端XMLHttpRequest、Fetch API、Axios实现文件上传、下载方法及后端Spring文件服务器处理方法
  • STM32智能交通监测系统教程
  • 【利用Selenium+autoIt实现文件上传】
  • python join
  • cython加速python代码
  • React@16.x(60)Redux@4.x(9)- 实现 applyMiddleware
  • level 6 day1 Linux网络编程之网络基础
  • PostgreSQL UPDATE 命令
  • 什么? CSS 将支持 if() 函数了?
  • function calling实现调用理杏仁api获取数据
  • Excel中用VBA实现Outlook发送当前工作簿
  • 从 ArcMap 迁移到 ArcGIS Pro
  • WSL2 的安装与运行 Linux 系统
  • 业务终端动态分配IP-DHCP技术、DHCP中继技术