QT开发技术【QTableView分页实现】

article/2025/8/2 9:29:49

一、引言

在开发桌面应用程序时,当需要展示大量数据到表格中,一次性加载所有数据可能会导致界面卡顿、响应缓慢,甚至内存溢出。QTableView 是 Qt 框架中用于展示表格数据的强大组件,结合 QAbstractTableModel 可以实现数据的分页展示,提升用户体验和应用性能。本文将详细介绍如何通过返回数据分页的方式实现 QTableView 的数据分页功能。

二、分页原理概述

分页的核心思想是将大量数据分成多个较小的“页”,每次只加载和显示其中一页的数据。在 QTableView 中,这通常通过自定义 QAbstractTableModel 来实现。QAbstractTableModel 是一个抽象基类,需要我们重写一些关键方法,如 rowCount()、columnCount()、data() 等,以实现分页逻辑。

三、分页效果

可上下切换,修改分页大小
在这里插入图片描述

四、实现原理

继承 QAbstractTableModel 实现 data()
重写 data() 方法
data() 方法用于返回指定位置的数据。在分页实现中,要根据当前页码和每页显示的数据数量计算出实际数据的索引。


QVariant CRelateDataModel::data(const QModelIndex& index, int role) const
{if (!index.isValid()){return QVariant();}const int row = index.row();const int nColumn = index.column();if (nColumn < m_ModelRelatedHead.GetHeadCount()) [[likely]]{std::shared_ptr<CRelateModelData> pRelateModelData = m_pRelateModelObject->GetRecordData().at(row);if (!pRelateModelData) [[unlikely]]{return QVariant();}QModelIndex modelIndex = createIndex(row, m_ModelRelatedHead.m_vecHeadInfos[nColumn].m_nHeadID);return pRelateModelData->GetData(modelIndex, role);}return QVariant();
}
class CGC_CORE_EXPORT CRemoteTestParaDefineManager : public CRelateModelObject

数据通过继承模板关联数据基类返回数据控制

将所有数据和展示数据分开

RemoteTestParaDefineVec  m_vecRemoteTestParaDefines;
RemoteTestParaDefineVec m_vecShowRemoteTestParaDefines;

实现分页控制功能,包含上一页、下一页、跳转到指定页等操作

void CRemoteTestParaDefineManager::SetPageSize(int nPageSize)
{m_nPageSize = nPageSize;m_vecShowRemoteTestParaDefines.clear();for (auto& itr : m_vecRemoteTestParaDefines){if ((int)m_vecShowRemoteTestParaDefines.size() < m_nPageSize){m_vecShowRemoteTestParaDefines.push_back(itr);}}
}int CRemoteTestParaDefineManager::GetPageSize() const
{return m_nPageSize;
}int CRemoteTestParaDefineManager::GetTotalPageSize() const
{return m_vecRemoteTestParaDefines.size() / m_nPageSize +  (m_vecRemoteTestParaDefines.size() % m_nPageSize == 0 ? 0 : 1);
}void CRemoteTestParaDefineManager::SetPageNum(int nPageNum)
{m_vecShowRemoteTestParaDefines.clear();int nStart = (nPageNum - 1) * m_nPageSize;int nEnd = nPageNum * m_nPageSize;for (int i = nStart; i < nEnd && i < (int)m_vecRemoteTestParaDefines.size(); ++i){m_vecShowRemoteTestParaDefines.push_back(m_vecRemoteTestParaDefines[i]);}
}int CRemoteTestParaDefineManager::GetRecordDataCount() const
{if (m_ePageType == E_PAGE_DATA_SHOW){return m_vecShowRemoteTestParaDefines.size();}else {return m_vecRemoteTestParaDefines.size();}
}std::vector<std::shared_ptr<CRelateModelData>> CRemoteTestParaDefineManager::GetRecordData() const
{std::vector<std::shared_ptr<CRelateModelData>> vecData;if (m_ePageType == E_PAGE_DATA_SHOW){for (auto& itr : m_vecShowRemoteTestParaDefines){vecData.push_back(itr);}}else{for (auto& itr : m_vecRemoteTestParaDefines){vecData.push_back(itr);}}return vecData;
}
void CDigMeasRemoteTestWidget::on_pushButton_UpPage_clicked()
{int nPageNum = ui->lineEdit_PageNum->text().toInt();if (nPageNum == 1){return;}m_nPageNum = nPageNum - 1;m_pParaDefineManager->SetPageNum(m_nPageNum);ui->lineEdit_PageNum->setText(QString::number(m_nPageNum));ui->tableView_ParaDefineManager->ResetModel();
}void CDigMeasRemoteTestWidget::on_pushButton_DownPage_clicked()
{int nPageNum = ui->lineEdit_PageNum->text().toInt();if (nPageNum == m_pParaDefineManager->GetTotalPageSize()){return;}m_nPageNum = nPageNum + 1;m_pParaDefineManager->SetPageNum(m_nPageNum);ui->lineEdit_PageNum->setText(QString::number(m_nPageNum));ui->tableView_ParaDefineManager->ResetModel();
}void CDigMeasRemoteTestWidget::on_lineEdit_PageNum_textChanged(const QString& qstrText)
{int nPageNum = qstrText.toInt();if (nPageNum < 1 || nPageNum > m_pParaDefineManager->GetTotalPageSize()){ui->lineEdit_PageNum->setText(QString::number(m_nPageNum));return;}m_nPageNum = nPageNum;m_pParaDefineManager->SetPageNum(m_nPageNum);ui->tableView_ParaDefineManager->ResetModel();
}void CDigMeasRemoteTestWidget::on_pushButton_SetPageSize_clicked()
{if (m_pParaDefineManager){m_pParaDefineManager->SetPageSize(ui->lineEdit_PageSize->text().toInt());ui->lineEdit_PageNum->setText("1");int nTotalPage = m_pParaDefineManager->GetTotalPageSize();ui->label_PageNum->setText("/" + QString::number(nTotalPage));ui->tableView_ParaDefineManager->ResetModel();}
}

总结

通过自定义 QAbstractTableModel 并重写关键方法,可以实现 QTableView 的数据分页功能。这种方式通过返回数据分页,每次只加载和显示当前页的数据,有效减少了内存占用,提升了界面响应速度。同时,通过实现分页控制功能,用户可以方便地浏览大量数据。在实际应用中,可以根据需求调整每页显示的数据数量,进一步优化用户体验。


http://www.hkcw.cn/article/YQaYtGkiiV.shtml

相关文章

新增Vulkan支持|UWA Gears V1.1.0

UWA Gears 是UWA最新发布的无SDK性能分析工具。针对移动平台&#xff0c;提供了实时监测和截帧分析功能&#xff0c;帮助您精准定位性能热点&#xff0c;提升应用的整体表现。 本次版本更新主要是Frame Capture模式新增对Vulkan项目的支持&#xff0c;进一步满足使用Vulkan开发…

mapbox高阶,PMTiles介绍,MBTiles、PMTiles对比,加载PMTiles文件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️PMTiles介绍1.5…

Sums of Sliding Window Maximum_abc407F分析与解答

倒着考虑&#xff0c;考虑每个a_i对哪些k值做出贡献&#xff0c;对一个a_i&#xff0c;定义L_i和R_i为&#xff1a; 以上笔误&#xff1a;R_i的定义应该是&#xff1a;连续最多R_i个元素比a_i 小 如果得到了 L_i和R_i&#xff0c;我们从k的长度从小到大依次看看&#xff0c;a_…

用通义灵码2.5打造智能倒计时日历:从零开始的Python开发体验

前言:为什么选择通义灵码2.5? 通义灵码2.5版本带来了令人兴奋的升级,特别是全新的智能体模式让编程体验焕然一新。作为一名长期关注AI编程助手的开发者,我决定通过开发一个实用的倒计时日历小工具,来全面体验通义灵码2.5的各项新特性。 一、项目构思与智能体协作 首先,…

历年西安电子科技大学计算机保研上机真题

2025西安电子科技大学计算机保研上机真题 2024西安电子科技大学计算机保研上机真题 2023西安电子科技大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 查找不同的连续数字串个数 题目描述 给定一个数字串&#xff0c;查找其中不同的连续数字串的个…

一文读懂 STP:交换机接口状态详解及工作原理

一文读懂 STP&#xff1a;交换机接口状态详解及工作原理 一. 引言&#xff1a;STP 是什么&#xff0c;为何如此重要&#xff1f;二. STP 的核心作用&#xff1a;避免网络环路2.1 什么是 STP&#xff1f;2.2 STP 的核心概念 三. STP 交换机接口状态详解四. STP 的工作原理&#…

清华大学发Nature!光学工程+神经网络创新结合

2025深度学习发论文&模型涨点之——光学工程神经网络 清华大学的一项开创性研究成果在《Nature》上发表&#xff0c;为光学神经网络的发展注入了强劲动力。该研究团队巧妙地提出了一种全前向模式&#xff08;Fully Forward Mode&#xff0c;FFM&#xff09;的训练方法&…

PHP学习笔记(十一)

类常量 可以把在类中始终保持不变的值定义为常量&#xff0c;类常量的默认可见性是public。 接口中也可以定义常量。 可以用一个变量来动态调用类&#xff0c;但该变量的值不能为关键字 需要注意的是类常量只为每个类分配一次&#xff0c;而不是为每个类的实例分配。 特殊的…

NodeMediaEdge快速上手

NodeMediaEdge快速上手 简介 NodeMediaEdge是一款部署在监控摄像机网络前端中&#xff0c;拉取Onvif或者rtsp/rtmp/http视频流并使用rtmp/kmp推送到公网流媒体服务器的工具。 通过云平台协议注册到NodeMediaServer后&#xff0c;可以同NodeMediaServer结合使用。使用图形化的…

强化学习的前世今生(五)— SAC算法

书接前四篇 强化学习的前世今生&#xff08;一&#xff09; 强化学习的前世今生&#xff08;二&#xff09; 强化学习的前世今生&#xff08;三&#xff09;— PPO算法 强化学习的前世今生&#xff08;四&#xff09;— DDPG算法 本文为大家介绍SAC算法 7 SAC 7.1 最大熵强化…

优质电子实验记录本如何确保数据不泄密?

实验数据是企业和科研机构的核心资产&#xff0c;承载着创新成果与竞争优势&#xff0c;选择合适的实验记录载体至关重要。本文从传统纸质记录的安全性优劣势出发&#xff0c;对比分析普通电子实验记录本存在的安全问题&#xff0c;详细阐述优质电子实验记录本如何构建数据防护…

RFID 助力钢铁钢帘线生产效率质量双提升

RFID 助力钢铁钢帘线生产效率质量双提升 应用背景 钢铁钢帘线广泛应用于建筑、公路、桥梁、隧道、海洋工程等领域。&#xff0c;其质量和生产效率直接影响性能与安全性。在钢铁钢帘线的生产过程中&#xff0c;面临着诸多挑战。传统生产模式下&#xff0c;各生产环节信息传递不…

4.5V~100V, 3.8A 峰值电流限, 非同步, 降压转换器,LA1823完美替换MP9487方案

一&#xff1a;综述 LA1823 是一款易用的非同步&#xff0c;降压转换器。 该模块集成了 500mΩ 低导通阻抗的高侧 MOSFET。LA1823 使用 COT 控制技术。此种控制方式有利于快速动态响应,同时简化了反馈环路的设计。LA1823 可以提供最大 2A 的持续负载电流。LA1823有150kHz/240kH…

多杆合一驱动城市空间治理智慧化

引言&#xff1a;城市“杆林困境”与智慧化破局 走在现代城市的街道上&#xff0c;路灯、监控、交通信号灯、5G基站等杆体林立&#xff0c;不仅侵占公共空间&#xff0c;更暴露了城市治理的碎片化问题。如何让这些“沉默的钢铁”升级为城市的“智慧神经元”&#xff1f;答案在…

ElasticSearch迁移至openGauss

Elasticsearch 作为一种高效的全文搜索引擎&#xff0c;广泛应用于实时搜索、日志分析等场景。而 openGauss&#xff0c;作为一款企业级关系型数据库&#xff0c;强调事务处理与数据一致性。那么&#xff0c;当这两者的应用场景和技术架构发生交集时&#xff0c;如何实现它们之…

搭建 Select 三级联动架构-东方仙盟插件开发 JavaScript ——仙盟创梦IDE

三级级联开卡必要性 在 “东方仙盟” 相关插件开发中&#xff0c;使用原生 HTML 和 JavaScript 实现三级联动选择&#xff08;如村庄 - 建筑 - 单元的选择&#xff09;有以下好处和意义&#xff0c;学校管理&#xff1a; 对游戏体验的提升 增强交互性&#xff1a;玩家能够通…

SpringBoot+vue+SSE+Nginx实现消息实时推送

一、背景 项目中消息推送&#xff0c;简单的有短轮询、长轮询&#xff0c;还有SSE&#xff08;Server-Sent Events&#xff09;、以及最强大复杂的WebSocket。 至于技术选型&#xff0c;SSE和WebSocket区别&#xff0c;网上有很多&#xff0c;我也不整理了&#xff0c;大佬的链…

软件测试的分类

为什么要软件测试分类呢&#xff1f; 软件测试是软件生命周期中的一个重要的环节&#xff0c;基本伴随着软件整个生命周期&#xff0c;对软件测试分类后&#xff0c;我们可以根据软件生命不同阶段&#xff0c;进行对应的测试&#xff0c;这样就有助于我们条理分明&#xff0c;…

<PLC><socket><西门子>基于西门子S7-1200PLC,实现手机与PLC通讯(通过websocket转接)

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…

实现一个免费可用的文生图的MCP Server

概述 文生图模型为使用 Cloudflare Worker AI 部署 Flux 模型&#xff0c;是参照视频https://www.bilibili.com/video/BV1UbkcYcE24/?spm_id_from333.337.search-card.all.click&vd_source9ca2da6b1848bc903db417c336f9cb6b的复现Cursor MCP Server实现是参照文章https:/…