Qt实现类似淘宝商品看板的界面,带有循环翻页以及点击某页跳转的功能

 效果如下:

#ifndef ModelDashboardGroup_h__
#define ModelDashboardGroup_h__#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QWidget>#include <QLabel>
#include <QWidget>
#include <QMouseEvent>class ClickableLabel : public QLabel {Q_OBJECTpublic:explicit ClickableLabel(QWidget* parent = nullptr) : QLabel(parent) {}signals:void clicked();protected:void mousePressEvent(QMouseEvent* event) override{if (event->button() == Qt::LeftButton) {emit clicked();}QLabel::mousePressEvent(event);}
};QT_BEGIN_NAMESPACE
namespace Ui { class CModelDashboardGroup; };
QT_END_NAMESPACEclass CModelDashboardGroup : public QWidget
{Q_OBJECTpublic:CModelDashboardGroup(QWidget *parent = nullptr);~CModelDashboardGroup();void SetItemWidgetInfos(const std::vector<std::pair<QString, QString> >& vecItemWidgetInfo);void AddItemWidgetInfo(const QString& strModelName, const QString& strModelImagePath);// 设置每页展示的模型图片数量void SetPerPageItemsNumber(int nNumber);// 设置展示页数的Label数量void SetMaxPageLabelCount(int nMaxPages);// 设置每行展示的模型图片的数量void SetPerColItemsNumber(int nNumber);private:void Init();void AddItemToGrid(int nIndex);void UpdateGrid();void UpdatePageLabels();int CalculateStartPage() const;private slots:void SlotPageButtonClicked();void SlotPageLabelClicked(int nIndex);private:Ui::CModelDashboardGroup *ui;std::vector<std::pair<QString, QString> > m_vecItemWidgetInfo;// 第一个QString表示模型名称,第二个QString表示模型展示图片路径QGridLayout* m_pGridLayout;QHBoxLayout* m_pPageControlLayout;QPushButton* m_pPrevButton;QPushButton* m_pNextButton;QList<ClickableLabel*> m_listPageLabels;int m_nCurrentPage;int m_nPerPageItemsNumber;int m_nPerRowPageItemsNumber;int m_nTotalPages;int m_nMaxPageLabels;
};#endif // ModelDashboardGroup_h__
#include "ui_ModelDashboardGroup.h"#include "ModelDashboardGroup.h"
#include "ModelDashboard.h"
#include <QGraphicsOpacityEffect>CModelDashboardGroup::CModelDashboardGroup(QWidget *parent): QWidget(parent), ui(new Ui::CModelDashboardGroup()), m_pGridLayout(NULL), m_pPrevButton(NULL), m_pNextButton(NULL), m_nCurrentPage(0), m_nPerPageItemsNumber(10), m_nPerRowPageItemsNumber(5), m_nTotalPages(1), m_nMaxPageLabels(5)
{ui->setupUi(this);//setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);//去掉标题栏setAttribute(Qt::WA_TranslucentBackground, true);//设置窗口背景透明Init();// 测试数据if (1){std::vector<std::pair<QString, QString> > vecItemWidgetInfo;for (int i = 1; i <= 105; ++i){  // 增加商品数量以测试分页vecItemWidgetInfo.push_back(std::make_pair(QString::fromLocal8Bit("模型%1").arg(i), QString::fromLocal8Bit(":/dotnetIcon.png")));}SetItemWidgetInfos(vecItemWidgetInfo);}else{UpdatePageLabels();UpdateGrid();}
}CModelDashboardGroup::~CModelDashboardGroup()
{delete ui;
}void CModelDashboardGroup::SetItemWidgetInfos(const std::vector<std::pair<QString, QString>>& vecItemWidgetInfo)
{m_vecItemWidgetInfo.clear();m_vecItemWidgetInfo = vecItemWidgetInfo;m_nTotalPages = (m_nPerPageItemsNumber + static_cast<int>(m_vecItemWidgetInfo.size()) - 1) / m_nPerPageItemsNumber;UpdatePageLabels();UpdateGrid();
}void CModelDashboardGroup::AddItemWidgetInfo(const QString& strModelName, const QString& strModelImagePath)
{m_vecItemWidgetInfo.push_back(std::make_pair(strModelName, strModelImagePath));m_nTotalPages = (m_nPerPageItemsNumber + static_cast<int>(m_vecItemWidgetInfo.size()) - 1) / m_nPerPageItemsNumber;UpdatePageLabels();UpdateGrid();
}void CModelDashboardGroup::SetPerPageItemsNumber(int nNumber)
{m_nPerPageItemsNumber = nNumber;
}void CModelDashboardGroup::SetMaxPageLabelCount(int nMaxPages)
{m_nMaxPageLabels = nMaxPages;
}void CModelDashboardGroup::SetPerColItemsNumber(int nNumber)
{m_nPerRowPageItemsNumber = nNumber;
}void CModelDashboardGroup::Init()
{QVBoxLayout* pMainLayout = new QVBoxLayout(this);QWidget* pGridWidget = new QWidget(this);m_pGridLayout = new QGridLayout(pGridWidget);m_pGridLayout->setSpacing(10);m_pPageControlLayout = new QHBoxLayout();m_pPrevButton = new QPushButton(QString::fromLocal8Bit("上一页"));m_pPrevButton->setFixedSize(QSize(75, 37));m_pPrevButton->setCursor(Qt::PointingHandCursor);m_pPrevButton->setStyleSheet("QPushButton {""width: 75px;""height: 37px;""background-color: #0097ee;""border-radius: 5px;""color: white;""font-size:10pt;""font-weight: bold;""font-family: Microsoft YaHei;""padding-bottom:2px;""}");m_pNextButton = new QPushButton(QString::fromLocal8Bit("下一页"));m_pNextButton->setFixedSize(QSize(75, 37));m_pNextButton->setCursor(Qt::PointingHandCursor);m_pNextButton->setStyleSheet("QPushButton {""width: 75px;""height: 37px;""background-color: #0097ee;""border-radius: 5px;""color: white;""font-size:10pt;""font-weight: bold;""font-family: Microsoft YaHei;""padding-bottom:2px;""}");//QLabel* pPageLabel = new QLabel("1");connect(m_pPrevButton, &QPushButton::clicked, this, &CModelDashboardGroup::SlotPageButtonClicked);connect(m_pNextButton, &QPushButton::clicked, this, &CModelDashboardGroup::SlotPageButtonClicked);m_pPageControlLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));m_pPageControlLayout->addWidget(m_pPrevButton);m_pPageControlLayout->addWidget(m_pNextButton);m_pPageControlLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));pMainLayout->addWidget(pGridWidget);pMainLayout->addLayout(m_pPageControlLayout);
}void CModelDashboardGroup::AddItemToGrid(int nIndex)
{CModelDashboard* pModelDashboard = new CModelDashboard();// 自定义widget替换为自己的类if (nIndex >= 0 && nIndex < m_vecItemWidgetInfo.size()){pModelDashboard->SetModelDisPlayName(m_vecItemWidgetInfo[nIndex].first);pModelDashboard->SetModelDisPlayImage(m_vecItemWidgetInfo[nIndex].second);}else{// 添加示例商品pModelDashboard->SetModelDisPlayName(QString::fromLocal8Bit("模型"));pModelDashboard->SetModelDisPlayImage(QString::fromLocal8Bit(":/dotnetIcon.png"));}int nRow = (m_pGridLayout->count() / m_nPerRowPageItemsNumber);  // 计算行数int nCol = (m_pGridLayout->count() % m_nPerRowPageItemsNumber);  // 计算列数m_pGridLayout->addWidget(pModelDashboard, nRow, nCol);
}void CModelDashboardGroup::UpdateGrid()
{// 清空现有网格布局QLayoutItem* pItem;while ((pItem = m_pGridLayout->takeAt(0)) != NULL){delete pItem->widget();delete pItem;}int nStartIndex = m_nCurrentPage * m_nPerPageItemsNumber;int nEndIndex = qMin(nStartIndex + m_nPerPageItemsNumber, static_cast<int>(m_vecItemWidgetInfo.size()));// 添加实际模型for (int i = nStartIndex; i < nEndIndex; ++i){AddItemToGrid(i);}// 如果最后一页商品不足一页,则添加示例int nNumPlaceholders = m_nPerPageItemsNumber - (nEndIndex - nStartIndex);for (int i = 0; i < nNumPlaceholders; ++i){AddItemToGrid(-1);  // 使用负索引来添加示例}UpdatePageLabels();m_pPrevButton->setEnabled(m_nTotalPages > 1); // Enable/disable based on totalPagesm_pNextButton->setEnabled(m_nTotalPages > 1); // Enable/disable based on totalPages
}void CModelDashboardGroup::UpdatePageLabels()
{// 清除现有的页码标签for (int i = 0; i < m_listPageLabels.size(); i++){ClickableLabel* pClickableLabel = m_listPageLabels.at(i);if (NULL != pClickableLabel){m_pPageControlLayout->removeWidget(pClickableLabel);pClickableLabel->deleteLater();}}m_listPageLabels.clear();// 在 items 为空时至少显示一个页码标签int nNumLabels = qMax(1, qMin(m_nTotalPages, m_nMaxPageLabels));int nStartPage = CalculateStartPage();for (int i = 0; i < nNumLabels; ++i){ClickableLabel* pLabel = new ClickableLabel();pLabel->setAlignment(Qt::AlignCenter);pLabel->setStyleSheet("QLabel {""width: 37px;""height: 37px;""background-color: #293d70;""border-radius: 5px;""color: white;""font-size:10pt;""font-weight: bold;""font-family: Microsoft YaHei;""padding-bottom:2px;""}");//QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect;//opacityEffect->setOpacity(0.4);//pLabel->setGraphicsEffect(opacityEffect);pLabel->setFixedSize(QSize(37, 37));pLabel->setText(QString::number(nStartPage + i + 1));pLabel->setCursor(Qt::PointingHandCursor);m_listPageLabels.append(pLabel);m_pPageControlLayout->insertWidget(m_pPageControlLayout->count() - 2, pLabel); // 插入在按钮之前connect(pLabel, &ClickableLabel::clicked, this, [this, i](){SlotPageLabelClicked(i);});if (nStartPage + i == m_nCurrentPage){pLabel->setStyleSheet("QLabel {""width: 37px;""height: 37px;""background-color: #0097ee;""border-radius: 5px;""color: white;""font-size:10pt;""font-weight: bold;""font-family: Microsoft YaHei;""padding-bottom:2px;""}");}}
}int CModelDashboardGroup::CalculateStartPage() const
{if (m_nTotalPages <= m_nMaxPageLabels){return 0;}if (m_nCurrentPage <= m_nMaxPageLabels / 2){return 0;}if (m_nCurrentPage >= m_nTotalPages - (m_nMaxPageLabels / 2)){return m_nTotalPages - m_nMaxPageLabels;}return m_nCurrentPage - (m_nMaxPageLabels / 2);
}void CModelDashboardGroup::SlotPageButtonClicked()
{QPushButton* pPushButton = qobject_cast<QPushButton*>(sender());if (pPushButton == m_pPrevButton){// 循环到最后一页m_nCurrentPage = (m_nCurrentPage > 0) ? (m_nCurrentPage - 1) : (m_nTotalPages - 1);}else if (pPushButton == m_pNextButton){// 循环到第一页m_nCurrentPage = (m_nCurrentPage < m_nTotalPages - 1) ? (m_nCurrentPage + 1) : 0;}UpdatePageLabels();UpdateGrid();
}void CModelDashboardGroup::SlotPageLabelClicked(int nIndex)
{int nStartPage = CalculateStartPage();int nNewPage = nStartPage + nIndex;if (nNewPage >= 0 && nNewPage < m_nTotalPages){m_nCurrentPage = nNewPage;UpdatePageLabels();UpdateGrid();}
}

修改AddItemToGrid接口中的CModelDashboard类即可,修改为自己需要展示的widget。

以下为一个示例:

 

#pragma once#include <QWidget>
#include "ui_ModelDashboard.h"QT_BEGIN_NAMESPACE
namespace Ui { class CModelDashboard; };
QT_END_NAMESPACEclass CModelDashboard : public QWidget
{Q_OBJECTpublic:CModelDashboard(QWidget *parent = nullptr);~CModelDashboard();void SetModelDisPlayImage(const QString& strImagePath);void SetModelDisPlayName(const QString& strText);private:Ui::CModelDashboard *ui;
};
#include "ModelDashboard.h"CModelDashboard::CModelDashboard(QWidget *parent): QWidget(parent), ui(new Ui::CModelDashboard())
{ui->setupUi(this);
}CModelDashboard::~CModelDashboard()
{delete ui;
}void CModelDashboard::SetModelDisPlayImage(const QString& strImagePath)
{QPixmap pixmap(strImagePath);ui->labelImage->setPixmap(pixmap);
}void CModelDashboard::SetModelDisPlayName(const QString& strText)
{ui->labelText->setText(strText);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394983.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

扩展【从0制作自己的ros导航小车】C++_ROS_QT5联合编译,简单界面为ROS开发增添交互

从0制作自己的ros导航小车 前言一、环境搭建二、联合编译三、测试 前言 前面已经实现了导航功能&#xff0c;对于之后的一些开发&#xff0c;有交互能力是比较重要的&#xff0c;比如小车上连接一块屏幕&#xff0c;通过屏幕来选择模式&#xff0c;可视化等等。QT是不错的选择…

LVS是什么?以及LVS-NAT以及DR模式实验

目录 NAT LVS LVS集群的类型&#xff1a; LVS-NAT模式实验 环境准备&#xff1a; 实验步骤&#xff1a; LVS-DR模式实验 题目&#xff1a; 环境准备&#xff1a; 实验步骤&#xff1a; LVS-防火墙标签解决轮询调度问题 环境准备&#xff1a; 实验步骤&#xff1…

智界S7 小鹏P7 G3 G3i P5 G9 P7i G6 X9维修手册和电路图线路图接线资料更新

汽修帮手资料库提供各大厂家车型维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等&#xff0c;并长期保持高频率资料更新&#xff01; 覆盖车型2020-2024年智界S7 小鹏…

在VScode中导入conda环境的记录【原创】

今天在vscode编辑器中运行一个python代码&#xff0c;发现终端可以运行&#xff0c;但是编辑器中点击Run会显示缺包&#xff0c;但是python包明明是有的&#xff0c;在自己的conda环境中。后来发现&#xff0c;是vscode没有发现我自己创建的conda环境&#xff0c;在vscode中导入…

51单片机个人学习笔记16(红外遥控)

前言 本篇文章属于STC89C52单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 [1-1] 课程简介_哔哩…

Java封装原生ES

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.spring-data-es操作ES1.引入依赖2.application.yml配置uris3…

高频焊接设备配电系统无源滤波系统的设计

1、高频焊机系统谐波状况简介 变压器容量&#xff1a;S11-M-1600/10KVA&#xff08;105%&#xff09;/0.4KV 短路阻抗&#xff1a;3.9% 谐波负载情况&#xff1a;一台600KW高频焊接设备 型号&#xff1a;GGP600-0.3-HC 输入电压&#xff1a;380V 输出电压&#xff1a;0…

【Python机器学习】回归——示例:预测乐高玩具套装的价格

用回归法预测乐高套装价格的基本步骤&#xff1a; 1、收集数据&#xff1a;用Google Shopping的API收集到的数据 2、准备数据&#xff1a;从返回的JSON数据中抽取价格 3、分析算法&#xff1a;可视化并观察数据 4、训练算法&#xff1a;构建不同的模型&#xff0c;采用逐步线性…

操作ArkTS页面跳转及路由相关心得

本文为JS老狗原创。 当前端不得不关注的点&#xff1a;路由&#xff0c;今天聊一聊鸿蒙相关的一点心得。 总体上套路不意外&#xff0c;基本就是&#xff08;尤其是Web&#xff09;前端那些事&#xff1a;维护路由表、跳转带参数、历史堆栈操作&#xff0c;等等。 历史原因&…

设计模式20-备忘录模式

设计模式20-备忘录 动机定义与结构定义结构 C代码推导优缺点应用场景总结备忘录模式和序列化备忘录模式1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 序列化1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 对比总结 动机 在软件构建过…

云服务器和物理服务器的优缺点对比

云服务器优点在于灵活性强、成本效益高、易于扩展且支持全球化部署&#xff1b;缺点则包括安全性与可控性相对较弱&#xff0c;性能可能受限&#xff0c;以及存在服务中断风险。物理服务器则以其高性能、高稳定性、强安全性和完全可控性著称&#xff0c;但成本较高、扩展性受限…

鸿蒙OS ArkTS 省市县级联选择框,封装组件

背景&#xff1a; 公司现在要开发纯血鸿蒙版本APP&#xff0c;我被抽调过来做点功能。现在要做一个省市县级联选择框&#xff0c;并且要封装为组件&#xff0c;供其他页面模块使用。 效果图&#xff1a; 难点&#xff1a; 1. 现在官方文档上只是查到了TextPicker组件是可以做…

Vue3+setup使用vuemap/vue-amap实现地图相关操作

首先要下载依赖并且引入 npm安装 // 安装核心库 npm install vuemap/vue-amap --save// 安装loca库 npm install vuemap/vue-amap-loca --save// 安装扩展库 npm install vuemap/vue-amap-extra --save cdn <script src"https://cdn.jsdelivr.net/npm/vuemap/vue-a…

软件测试需要具备的基础知识【功能测试】---前端知识(三)

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 为了更好的学习软件测试的相关技能&#xff0c;需要具备一定的基础知识。需要学习的基础知识包括&#xff1a; 1、计算机基础 2、前端知识 3、后端知识 4、软件测试理论 后期分四篇文章进行编写&#xff0c;这是第二篇 …

使用es-hadoop同步hive和es之间数据

&#x1f4bb;近期在华为云连接es时的时候发现不能输入账号密码&#xff0c;后面联系华为工程师了解到&#xff0c;华为云默认是非安全模式&#xff0c;即不需要输入账号密码。 如果对你有所帮助&#xff0c;欢迎点赞收藏关注不迷路哦&#x1f493; 目录 使用es-hadoop同步h…

AI时代,我们还可以做什么?

最近看了本书&#xff0c;书名叫做《拐点&#xff1a;站在 AI 颠覆世界的前夜》&#xff0c;作者是万维钢。 本想着看完后&#xff0c;就能掌握一整套 AI 技巧&#xff0c;结果——竟然学了很多道理。 这本书讨论了以下话题&#xff1a; 我们该怎么理解这个 AI 大时代的哲学&am…

国产数据库备份恢复实现

数据库备份恢复是数据库高可用的基本能力&#xff0c;如何通过备份数据快速高效的恢复业务并且满足不同场景下的恢复需求&#xff0c;是各数据库厂商需要关注的要点。本文将介绍几种国产数据库的备份恢复功能&#xff0c;以加深了解。 1、数据库备份恢复方案 数据库备份是生产…

函数实例讲解(七)

文章目录 清洗数据的函数&#xff08;TRIM、CLEAN&#xff09;1、TRIM2、CLEAN3、CONCATENATE4、TEXTJOIN 函数综合练习COUNTIF Excel函数总结1、判断类2、求和类3、计数类4、求平均5、查找引用类6、求数据极值类7、四舍五入类8、提取类9、日期类10、文本处理类11、随机数12、排…

基于SpringBoot+Vue的校园失物招领系统(带1w+文档)

基于SpringBootVue的校园失物招领系统(带1w文档) 基于SpringBootVue的校园失物招领系统(带1w文档) 本课题研发的校园失物招领系统管理系统&#xff0c;就是提供校园失物招领系统信息处理的解决方案&#xff0c;它可以短时间处理完信息&#xff0c;并且这些信息都有专门的存储设…

MyBatis 基本操作 - 注解版

目录 一&#xff0c;查询 - select 1.1 全列查询 1.2 指定列查询 1.3 赋值问题 方法一&#xff1a;起别名 方法二&#xff1a;结果映射 方法三&#xff1a;添加配置 二&#xff0c;新增 - Insert 2.1 使用对象插入 2.2 获取主键 三&#xff0c;删除 - Delete 四&am…