首页 > 其他分享 >QT实现滑动页面切换

QT实现滑动页面切换

时间:2024-10-16 20:49:00浏览次数:10  
标签:index widget QT int void CustomWidget QWidget 滑动 页面

1.界面实现效果

以下是具体的项目需要用到的效果展示。
在这里插入图片描述

2.简介

原理:使用Qt的QPropertyAnimation动画类,这里简单来说就是切换两个界面。
这个widget里面可以放很多个待切换的界面,每次切换的时候将当前界面和切换后的界面显示,其他界面都隐藏,然后当前界面移动到主界面之外,下一个界面移动到主界面里面。,当然这两个界面需要一起移动,不然滑动的中间会存在缝隙,就不美观。
以下是demo展示,原理都一样,只是中间的界面不一样而已,可以自定义。
在这里插入图片描述
中间定义的滚动CustomWidget类

#include <QWidget>
#include <QPropertyAnimation>
#include <QObject> 

class CustomWidget : public QWidget
{
	Q_OBJECT
public:
    CustomWidget(QWidget *parent);
    ~CustomWidget();
 
public:
    //数量
    int count() const;
    //当前显示的界面索引
    int currentIndex() const;
    //添加widget(任何widget都可以),返回索引值
    int addWidget(QWidget *widget);
    //索引
    int indexOf(QWidget *widget) const;
    //插入,返回索引值
    int insertWidget(int index, QWidget *widget);
    //当前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 &);
 
private:
	void moveAnimationStart();
	void setWidgetsVisible();
 
protected:
	void resizeEvent(QResizeEvent *event);
 
private:
    int m_offset = 0;
    int m_curIndex = 0;
    int m_lastIndex = 0;
 
    int m_duration = 500;
    QPropertyAnimation *m_moveAnimation = nullptr;
	QList<QWidget *> m_widgetLst;
};

#include "CustomWidget.h"
#include <QPropertyAnimation>
 
CustomWidget::CustomWidget(QWidget *parent)
	: QWidget(parent)
{
	m_moveAnimation = new QPropertyAnimation(this, "");
	m_moveAnimation->setDuration(m_duration);
    connect(m_moveAnimation, &QPropertyAnimation::valueChanged, this, &CustomWidget::onValueChanged);
}
 
CustomWidget::~CustomWidget()
{
 
}
 
int CustomWidget::count() const
{
	return m_widgetLst.size();
}
 
int CustomWidget::currentIndex() const
{
	return m_curIndex;
}
 
void CustomWidget::setDuration(int duration)
{
	m_duration = duration;
}
 
int CustomWidget::addWidget(QWidget * widget)
{
	int index = indexOf(widget);
	if (index >= 0){
		return index;
	}
	widget->setParent(this);
	m_widgetLst.append(widget);
	return count() - 1;
}
 
int CustomWidget::indexOf(QWidget * widget) const
{
	return m_widgetLst.indexOf(widget);
}
 
int CustomWidget::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 * CustomWidget::currentWidget() const
{
	if (m_curIndex >= 0 && m_curIndex < count()){
		return m_widgetLst.at(m_curIndex);
	}
    return 0;
}
 
QWidget * CustomWidget::widget(int index) const
{
	if (index >= 0 && index < count()) {
		return m_widgetLst.at(index);
	}
    return 0;
}
 
void CustomWidget::removeWidget(QWidget * widget)
{
	int index = indexOf(widget);
	if (index >= 0) {
		m_widgetLst.removeAll(widget);
		emit widgetRemoved(index);
	}
}
 
void CustomWidget::setCurrentWidget(QWidget * widget)
{
	int index = indexOf(widget);
	if (index >= 0 && m_curIndex != index) {
		setCurrentIndex(index);
	}
}
 
void CustomWidget::setCurrentIndex(int index)
{
	if (index >= 0 && m_curIndex != index) {
		m_lastIndex = m_curIndex;
		m_curIndex = index;	
		moveAnimationStart();
		emit currentChanged(index);
	}
}
 
void CustomWidget::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 CustomWidget::onValueChanged(const QVariant &value)
{
	if (m_widgetLst.size() == 0)
		return;
	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 CustomWidget::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 CustomWidget::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);
		}
	}
}

以下是示例CustomExampleWidget类(可以换成自己的widget)
在这里插入图片描述

3.使用

以下是mainwidget中,提升一下CustomWidget。
在这里插入图片描述

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_btnLeft_clicked();

    void on_btnRight_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"
#include "CustomExampleWidget.h"

unsigned int num = 0;

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QString num1[6] = {"1","2","3","4","5","6"};
    QString num2[6] = {"11","12","13","14","15","16"};
    QString num3[6] = {"21","22","23","24","25","26"};
    QString num4[6] = {"31","32","33","34","35","36"};

    int index = 0;
    CustomExampleWidget *widget1 = new CustomExampleWidget(ui->widget);
    widget1->setInfo(num1);
    index = ui->widget->addWidget(widget1);

    CustomExampleWidget *widget2 = new CustomExampleWidget(ui->widget);
    widget2->setInfo(num2);
    index = ui->widget->addWidget(widget2);

    CustomExampleWidget *widget3 = new CustomExampleWidget(ui->widget);
    widget3->setInfo(num3);
    index = ui->widget->addWidget(widget3);

    CustomExampleWidget *widget4 = new CustomExampleWidget(ui->widget);
    widget4->setInfo(num4);
    index = ui->widget->addWidget(widget4);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnLeft_clicked()
{
    num--;
    if(num<0)
        num = 0;
    ui->widget->setCurrentIndex(num);
}

void Widget::on_btnRight_clicked()
{
    num++;
    if(num > ui->widget->count()-1)
        num = ui->widget->count()-1;
    ui->widget->setCurrentIndex(num);
}

标签:index,widget,QT,int,void,CustomWidget,QWidget,滑动,页面
From: https://blog.csdn.net/wzz953200463/article/details/142991280

相关文章

  • 2-STM32F103+ML307(中移4G Cat1)OTA升级篇(自建物联网平台)-STM32通过ML307使用http或
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/ML307/myota.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  说明前面......
  • 如何修改网站后台的图片?php网站显示页面修改密码?
    针对你的问题,我将其分为两部分来解答:一是如何修改网站后台的图片;二是如何在PHP网站上实现密码修改功能。1.如何修改网站后台的图片步骤一:访问网站后台登录到你网站的管理员界面或控制面板。步骤二:查找媒体管理区域在大多数内容管理系统(如WordPress)中,会有一个“媒体”、“文件......
  • qt页面设计
    1.Designer设计师(掌握)Designer是Qt内置的一款界面设计程序,设计的界面文件为.ui格式。C++程序员通常不会单独启动Designer,如果要在项目中使用Designer程序,只需要在新建项目时,勾选“创建界面文件”选项。这样的项目自带dialog.ui,双击dialog.ui可以直接使用Designer程序......
  • 【Shiro】9.前端页面授权控制
     shiro可以与前端Thymeleaf结合,进行前端授权认证。由于,“吾生而有涯,而知而无涯”。所以,有限的生命不能照单全收无限的知识。而,前后端分离,必定是大趋势。所以,我就不额外写代码。截图记账理解一下。1.pom.xml页面引入Thymeleaf依赖。 2.配置类添加新配置 3.前端页面引入Sh......
  • yolov5,v8船舰识别检测(包含训练代码Pyqt源码超详细)
    前言:随着海上活动的增加,对船舰进行实时、准确的检测与识别成为了海上安全、海洋监测、海事管理等领域的迫切需求。传统的船舶识别方法主要依赖于船舶自动识别系统(AIS)和雷达等通信导航设备,但这些方法存在一定的局限性,例如目标误识别、目标丢失和易受环境噪声为海上船只的自动......
  • QT学习第一战串口调试助手(3)实现收发数据以及显示
    前情概述在之前的文章中我们以及完成了串口调试助手页面的制作,同时在打开串口按键的槽函数中实现串口的打开功能本章节将注重于实现在串口打开后数据的收发问题以及一系列优化本章流程准备工作 1.在头文件中定义以下变量privateslots:voidon_btnCloseorOpenSer......
  • Qt弹窗,点击非弹窗区域外,自动隐藏弹窗;
    //下面三个函数监听全局的隐藏事件,为了保证客户端不可见的时候日历隐藏boolCPlaybackCalendarWidget::eventFilter(QObject*watched,QEvent*eve){if(eve->type()==QEvent::ApplicationStateChange)//状态改变{if(qApp->a......
  • 修改当前路由地址参数重新刷新页面
    需求:不允许token暴漏在地址栏拿到token放到sessionStorage里面并重新刷新地址所有统一使用query的页面就直接替换为sessionStoragerouter.beforeEach((to,from,next)=>{//...其他代码...//检查是否有token参数if(to.query.token){//存储token到ses......
  • 怎么将PDF文件页面转换成图片-免费工具分享
    怎么将PDF文件页面转换成图片序言目前市面上有关pdf处理的工具有很多,不过绝大多数的PDF处理工具都需要付费使用,且很多厂商甚至连试用的机会也不给用户,有试用的,也是限制在几页内,这样就导致用户还没有办法确认你的软件是否满足需要,就要先付费购买会员或者授权,这极大的影响了用......
  • 基于RabbitMQ(windows)的MQTT(WSS)的安装配置和使用
    RabbitMQ官网地址https://www.rabbitmq.com/1.安装Erlang/OTP2.安装RabbitMQ3.开启后台管理rabbitmq-pluginsenablerabbitmq_managementhttp://127.0.0.1:15672/#/ 用户名密码默认guest4.开启mqttrabbitmq-pluginsenablerabbitmq_mqtt开启webmqttrabbitmq-pluginsenab......