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://xiahunao.cn/news/3246139.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

乐尚代驾项目概述

前言 2024年7月17日&#xff0c;最近终于在低效率的情况下把java及其生态的知识点背的差不多了&#xff0c;投了两个礼拜的简历&#xff0c;就一个面试&#xff0c;总结了几点原因。 市场环境不好 要知道&#xff0c;前两年找工作&#xff0c;都不需要投简历&#xff0c;把简历…

《绝区零》公测“翻车”

“《绝区零》重塑米哈游荣光”到“《绝区零》翻车米哈游没招了”,这样极与极的舆论反转,只用了不到一天的时间。 7月,米哈游自研游戏《绝区零》上线公测。虽然品类略显小众,主打动作手游,但系出名门的优势还是让《绝区零》在公测前预下载阶段大放异彩——直接登上了百余国…

Ubuntu/Kali简洁高效安装最新版的docker-compose

基于docker已安装的情况下&#xff0c;通过执行一下代码完成docker-compose的安装 sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep \"tag_name\": | sed …

区块链资料

Quantstamp - Public Security Assessments smart-contract-sanctuary-bsc/contracts/mainnet at master tintinweb/smart-contract-sanctuary-bsc GitHub https://github.com/slowmist/Cryptocurrency-Security-Audit-Guide/blob/main/README_CN.md sFuzz: 高效自适应的智…

有赞群团团开团大团长跑路,用户资金保护并没有保障到位!

近日群团团的开团大团长“肥肥购物”已经跑路了&#xff0c;留下了一堆烂账。有的团长5月21号买的购物卡到现在还没有进行成功交付&#xff0c;据帮卖团长反馈该笔订单一直没有确认收货且处于未完结的状态&#xff0c;但是这笔订单货款钱却迟迟无法进行成功退款。 下方是帮卖团…

Windows搭建RTMP视频流服务器

参考了一篇文章&#xff0c;见文末。 博客中nginx下载地址失效&#xff0c;附上一个有效的地址&#xff1a; Index of /download/ 另外&#xff0c;在搭建过程中&#xff0c;遇到的问题总结如下&#xff1a; 1 两个压缩包下载解压并重命名后&#xff0c;需要 将nginx-rtmp…

若依微服务集成手机短信验证码登陆

为了响应公司项目的特定需求&#xff0c;增强用户体验与安全性&#xff0c;集成手机短信验证码登录功能至基于若依微服务框架开发的应用中&#xff0c;故创作此篇为未来类似项目提供了可借鉴的实施范例。 文章目录 1.设计思路2.发送手机验证码接口3.发送手机验证码接口4.post请…

云动态摘要 2024-07-16

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 数据库上云优选 阿里云 2024-07-04 RDS、PolarDB、Redis、MongoDB 全系产品新用户低至首年6折起&#xff01; [免费体验]智能助手ChatBI上线 腾讯云 2024-07-02 基于混元大模型打造&…

开放式耳机性价比推荐!免费总结功课给你参考!

在选择适合自己的耳机时&#xff0c;确实需要考虑多方面的因素&#xff0c;包括音质、舒适度、佩戴方式、续航能力、防水性能等。开放式耳机因其独特的设计&#xff0c;不仅能够提供良好的音质体验&#xff0c;还能让你在享受音乐的同时&#xff0c;保持对周围环境的感知&#…

AI数字人直播源码解析:灰豚私有化部署背后的技术分析

随着AI数字人技术的应用潜力不断显现&#xff0c;与AI数字人相关的多个项目逐渐成为创业者们的重点关注对象&#xff0c;作为当前AI数字人典型应用场景之一的数字人直播意向人数更是屡创新高&#xff0c;AI数字人直播源码部署的热度也因此不断飙升&#xff0c;与各大数字人源码…

python-区间内的真素数(赛氪OJ)

[题目描述] 找出正整数 M 和 N 之间&#xff08;N 不小于 M&#xff09;的所有真素数。真素数的定义&#xff1a;如果一个正整数 P 为素数&#xff0c;且其反序也为素数&#xff0c;那么 P 就为真素数。 例如&#xff0c;11&#xff0c;13 均为真素数&#xff0c;因为 11 的反序…

Python入门------pycharm加载虚拟环境

pycharm虚拟环境配置&#xff1a; 在按照前面的办法&#xff0c;配置好虚拟环境后,如果我们需要到虚拟环境开发&#xff0c;就需要给编译器配置虚拟环境 1.打开编译器&#xff0c;点击右下角的interpreter选项 2. 点击ADD Interpreter,添加虚拟环境 3. 因为我们使用的是原始…

Hadoop安装报错

报错&#xff1a;ERROR 2023-03-09 21:33:00,178 NetUtil.py:97 - SSLError: Failed to connect. Please check openssl library versions. 解决方案: 在安装失败得客户端执行 编辑 /etc/python/cert-verification.cfg 配置文件&#xff0c;将 [https] 节的 verify 项 设为禁用…

linux上Mysql的安装

1.先检查有没有安装mariadb&#xff0c;有的话将其卸载&#xff0c;不然会和mysql冲突 [rootweb1 ~]# yum list | grep mariadb 2.卸载mariadb,按Y确认 [rootweb1 ~]# yum remove mariadb-libs.x86_64 3.下载mysql [rootweb1 ~]# wget https://downloads.mysql.com/archi…

大模型训练数据白皮书

大模型训练数据白皮书 关键要点一、合成数据解决方案探讨二、ChatGPT的案例分析三、大模型训练所需数据及特点四、多模态、知识性和安全性五、中文大模型发展受限于中式价值观类语料短缺六、高质量数据的重要性及其对模型的影响七、三重不确定性和有效搭配八、从质量、规模、多…

Self-Attention 自注意力机制(二)——实例过程说明

一、自注意力机制核心过程 自注意力机制&#xff08;Self-Attention Mechanism&#xff09;&#xff0c;也称为内部注意力机制&#xff0c;是一种在序列模型中用于捕捉序列内部不同位置之间依赖关系的技术。这种机制允许模型在处理序列时&#xff0c;对序列中的每个元素分配不…

pytorch-pytorch之LSTM

目录 1. nn.LSTM2. nn.LSTMCell 1. nn.LSTM 初始化函数输入参数与RNN相同&#xff0c;分别是input_size&#xff0c;hidden_size和num_layer foward函数也与RNN类似&#xff0c;只不过返回值除了out外&#xff0c;ht变为(ht,ct) 代码见下图&#xff1a; 2. nn.LSTMCell 初…

SAP ABAP性能优化

1.前言 ABAP作为SAP的专用的开发语言&#xff0c;衡量其性能的指标主要有以下两个方面&#xff1a; 响应时间&#xff1a;对于某项特定的业务请求&#xff0c;系统在收到请求后需要多久返回结果 吞吐量&#xff1a;在给定的时间能&#xff0c;系统能够处理的数据量 2. ABAP语…

React工程化笔记

脚手架可以帮助我们快速的搭建一个项目结构&#xff0c;在我们之前学习 webpack 的过程中&#xff0c;每次都需要配置 webpack.config.js 文件&#xff0c;用于配置我们项目的相关 loader 、plugin&#xff0c;这些操作比较复杂&#xff0c;但是它的重复性很高&#xff0c;而且…

SQL注入问题

一、什么是sql注入 public class TestSql {public static void main(String[] args) {Scanner inScanner new Scanner(System.in);System.out.println("请输入用户名");String username inScanner.nextLine();System.out.println("请输入密码");String …