news 2026/1/11 5:35:08

QTableWidget和QTableView插入数据比较

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
QTableWidget和QTableView插入数据比较

目录

1.前言

2.QTableWidget快速插入数据方法

3.QTableView高效方案

4.核心维度对比(关键差异)

5.典型使用场景


1.前言

数据展示使用最多的就是table控件了,在QT编程中,使用比较多的无外乎两种QTableWidget和QTableView,前者是开箱即用的封装型控件,后者是灵活的模型视图架构核心,二者的选择直接决定表格的性能、扩展性和维护成本。

它们的关系如下:

控件核心定位继承关系架构类型
QTableWidget封装了QTableView + 私有默认模型,提供 Item 直接操作接口,开箱即用QTableViewQAbstractItemViewItem-Based(基于项)
QTableView纯视图控件,无内置数据存储,需绑定自定义模型(如QAbstractTableModelQAbstractItemViewModel-View(模型视图分离)

简单来说:

QTableWidget = QTableView + 内置默认模型 + QTableWidgetItem 操作接口

QTableView是 “空壳视图”,必须搭配模型才能使用,灵活性更高。

2.QTableWidget快速插入数据方法

核心思路:关闭所有非必要 UI 开销,批量一次性插入,避免动态扩展和中间重绘。

  • 禁用 UI 更新 + 屏蔽信号(避免每插一条数据触发重绘 / 事件);
  • 提前设置总行 / 列数(替代insertRow,避免动态扩容开销);
  • 批量创建 Item(减少new调用和setText重复操作);
  • 禁用排序 / 自动滚动(插入后统一处理)。

示例代码:

#include <QTableWidget> #include <QElapsedTimer> #include <QDebug> void efficientInsertMediumData(QTableWidget* table, int totalRows, int totalCols) { QElapsedTimer timer; timer.start(); // 1. 保存原始状态(插入后恢复,不影响后续使用) const bool oldUpdate = table->updatesEnabled(); const bool oldSignal = table->signalsBlocked(); const bool oldSort = table->isSortingEnabled(); const bool oldScroll = table->verticalScrollBar()->isEnabled(); // 2. 关闭所有性能消耗项 table->setUpdatesEnabled(false); // 核心:禁止UI重绘 table->blockSignals(true); // 屏蔽 itemChanged 等信号 table->setSortingEnabled(false); // 关闭实时排序 table->verticalScrollBar()->setEnabled(false); // 禁用滚动条(避免滚动触发重绘) // 3. 一次性预留行列空间(关键:避免动态扩展) table->setRowCount(totalRows); table->setColumnCount(totalCols); // 4. 批量插入数据(循环内仅做必要操作) for (int row = 0; row < totalRows; ++row) { // 可选:复用Item模板(如果数据格式固定,减少new开销) for (int col = 0; col < totalCols; ++col) { // 直接构造时赋值,避免单独调用 setText QTableWidgetItem* item = new QTableWidgetItem( QString("R%1-C%2").arg(row).arg(col) ); // 批量设置属性(如禁用编辑、对齐方式),避免循环外重复操作 item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setTextAlignment(Qt::AlignCenter); table->setItem(row, col, item); } } // 5. 统一恢复状态+一次性处理UI(仅触发1次重绘) table->verticalScrollBar()->setEnabled(oldScroll); table->setSortingEnabled(oldSort); table->blockSignals(oldSignal); table->setUpdatesEnabled(oldUpdate); // 统一调整列宽(最后执行,避免中间重绘) table->resizeColumnsToContents(); qDebug() << "插入" << totalRows << "行数据耗时:" << timer.elapsed() << "ms"; } // 调用方式 // QTableWidget* table = new QTableWidget(this); // efficientInsertMediumData(table, 100000, 5); // 10万行耗时≈30ms

3.QTableView高效方案

QTableWidgetItem-based 架构(每个单元格对应一个QTableWidgetItem),10 万行以上会占用大量内存(每行 5 列≈50MB+),且渲染压力大,此时必须切换到Model-View 架构QTableView + 自定义模型),仅渲染可见区域,性能提升 100 倍以上。

  • 内存占用骤降(仅缓存可见行数据,100 万行也只占几 MB);
  • 渲染无延迟(只绘制当前屏幕可见的 10-20 行);
  • 支持动态数据加载(分页、懒加载)。

示例代码:

#include <QTableView> #include <QAbstractTableModel> #include <QElapsedTimer> #include <QDebug> // 自定义模型:仅提供可见行数据,不预加载所有Item class MassDataModel : public QAbstractTableModel { Q_OBJECT public: explicit MassDataModel(int totalRows, int totalCols, QObject* parent = nullptr) : QAbstractTableModel(parent), m_totalRows(totalRows), m_totalCols(totalCols) {} // 重写必要接口(模型核心) int rowCount(const QModelIndex& parent = QModelIndex()) const override { return m_totalRows; // 总数据行数(实际不加载,只返回计数) } int columnCount(const QModelIndex& parent = QModelIndex()) const override { return m_totalCols; } QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override { if (!index.isValid()) return QVariant(); // 仅当需要显示时,才生成数据(懒加载) if (role == Qt::DisplayRole) { return QString("R%1-C%2").arg(index.row()).arg(index.column()); } // 批量设置单元格属性(避免在UI层重复操作) else if (role == Qt::TextAlignmentRole) { return Qt::AlignCenter; } else if (role == Qt::ItemIsEditable) { return false; } return QVariant(); } private: int m_totalRows; // 总数据行数 int m_totalCols; // 总列数 }; // 调用方式(100万行无压力) void efficientInsertMassData(QTableView* view, int totalRows, int totalCols) { QElapsedTimer timer; timer.start(); // 1. 创建自定义模型(数据不预加载,瞬间完成) MassDataModel* model = new MassDataModel(totalRows, totalCols, view); // 2. 绑定模型到QTableView(模型视图分离) view->setModel(model); // 3. 优化视图性能 view->setUniformRowHeights(true); // 固定行高,减少布局计算 view->setSortingEnabled(false); // 如需排序,在模型中实现(更高效) view->resizeColumnsToContents(); qDebug() << "初始化" << totalRows << "行数据耗时:" << timer.elapsed() << "ms"; } // 使用示例 // QTableView* view = new QTableView(this); // efficientInsertMassData(view, 1000000, 5); // 100万行耗时≈5ms

两种插入数据方法性能比较:

电脑配置:

插入100w行数据输出信息:

4.核心维度对比(关键差异)

对比维度QTableWidgetQTableView
数据存储依赖QTableWidgetItem存储每个单元格数据无内置存储,数据由绑定的模型(如自定义QAbstractTableModel)管理
数据绑定手动创建QTableWidgetItemsetItem()绑定模型(setModel()),模型与视图解耦
大数据量支持差(1 万行以上卡顿 / 内存溢出,需大量优化)优(百万行级无压力,懒加载仅渲染可见行)
扩展性弱(仅支持简单编辑 / 样式,自定义逻辑需绕开封装)强(重写模型接口支持任意数据源 / 自定义渲染 / 业务逻辑)
多视图共享数据不支持(需手动同步多个QTableWidget数据)支持(一个模型绑定多个视图,数据变化自动同步)
自定义单元格渲染依赖setCellWidget()(效率低、内存占用高)模型data()函数通过角色(如Qt::DecorationRole)实现(高效)
使用复杂度低(开箱即用,无需子类化)高(需子类化模型,重写核心接口)
性能(10 万行)耗时≈30ms(需禁用重绘 / 信号等优化)耗时≈5ms(模型懒加载)
内存占用(10 万行)≈50MB+(每个 Item 占内存)≈几 MB(仅缓存可见行数据)

5.典型使用场景

✅ 选 QTableWidget 的场景

  • 简单静态表格(1000 行以内),无需复杂逻辑;
  • 快速开发原型、临时表格展示(如小工具的配置项表格);
  • 仅需基础功能(展示 / 简单编辑 / 排序),无自定义渲染 / 多数据源需求。

✅ 选 QTableView 的场景

  • 大数据量展示(1 万行以上,尤其是 10 万 / 百万行);
  • 多数据源整合(如同时对接数据库 / 文件 / 网络数据);
  • 需自定义业务逻辑(如单元格验证、权限控制、树形表格);
  • 多视图共享同一数据源(如主窗口表格 + 子窗口详情页同步);
  • 实时动态数据更新(如监控面板、股票行情)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/9 8:19:55

韩国大学团队破解全球船舶智能追踪难题:让大海不再是信息黑洞

这项由韩国大学工业与管理工程学院金振燮、朴现俊、申雨锡、韩成元教授团队与SeaVantage公司董日朴合作的突破性研究&#xff0c;发表于2023年的《IEEE航空航天与电子系统汇刊》。想要了解这项研究详细内容的读者&#xff0c;可以通过论文编号"arXiv:2512.13190v1"查…

作者头像 李华
网站建设 2026/1/9 10:06:31

腾讯AI团队突破:让AI学会自我指导,解决智能推理的根本难题

这项由腾讯AI实验室的梁振文、陆斯迪、俞文浩、基山帕纳甘蒂、周宇君、米海涛和俞栋等人共同完成的研究发表于2025年12月&#xff0c;论文编号为arXiv:2512.15687v1。有兴趣深入了解的读者可以通过该编号查询完整论文。这个研究团队中还有一位来自圣母大学的研究人员周宇君&…

作者头像 李华
网站建设 2026/1/9 15:34:35

miniaudio音频库:C语言开发者的终极音频处理解决方案

miniaudio音频库&#xff1a;C语言开发者的终极音频处理解决方案 【免费下载链接】miniaudio Audio playback and capture library written in C, in a single source file. 项目地址: https://gitcode.com/gh_mirrors/mi/miniaudio miniaudio是一个功能强大的单文件C语…

作者头像 李华
网站建设 2026/1/10 23:20:43

Langchain-ChatchatAPI文档生成:Swagger注解自动转说明

Langchain-Chatchat API文档生成&#xff1a;Swagger注解自动转说明 在企业加速智能化转型的今天&#xff0c;如何让私有知识“活”起来&#xff0c;成为每一个组织必须面对的问题。尤其在金融、医疗、政务等对数据安全要求极高的行业&#xff0c;将敏感文档接入公有云大模型几…

作者头像 李华
网站建设 2026/1/9 14:13:14

S7-1500PLC Modbus-RTU通信终极指南:快速掌握工业自动化通信技术

S7-1500PLC Modbus-RTU通信终极指南&#xff1a;快速掌握工业自动化通信技术 【免费下载链接】S7-1500PLCModbus-RTU通信详解分享 S7-1500PLC Modbus-RTU 通信详解 项目地址: https://gitcode.com/Open-source-documentation-tutorial/7c8db 在现代工业自动化系统中&…

作者头像 李华
网站建设 2026/1/10 18:18:32

Langchain-Chatchat负载均衡配置:应对高并发访问场景

Langchain-Chatchat负载均衡配置&#xff1a;应对高并发访问场景 在企业知识管理日益智能化的今天&#xff0c;越来越多组织开始部署基于大模型的本地问答系统。Langchain-Chatchat 作为开源社区中最具代表性的私有知识库解决方案之一&#xff0c;凭借其对文档解析、向量检索与…

作者头像 李华