Qt5中表格处理大数据量

Stella981
• 阅读 698

在Qt中如果是普通项目,GUI处理展现的数据量不大,一般用QTableWidget,QTreeWidget这样的控件就满足了,但是如果数据量行数达到了几万行,那么Widget的展示性能就偏差了。

Qt中提供了一种Model/View的编程方式来处理数据,也就是展示层和数据层分离,这样就解耦了。一旦Model的状态改变,它会自动渲染到View控件。这样的机制使得GUI可以展现大量的数据也不会卡顿。

为了处理数据的灵活性,我们用QStandardItemModel来做QTableView的Model层实现。因为以Table的形式展现,所以以下代码实现了,点击表头按列排序,点击行显式行的上下文菜单的功能。因为QTableView的默认

排序是按字符序列排序,所以得对QStandardItem进行子类化,并重载operator< 函数才能达到某些列用数值大小来排序。

因为是简单的Demo例子,QTableView是采用拖拽空间的方式拖到一个Widget里面的,该Wdiget类为ModelViewTable:

Qt5中表格处理大数据量

1 // ModelViewTable.h 2 #pragma once 3 4 #include <QtWidgets/QWidget> 5 #include "ui_ModelViewTable.h" 6 7 class QStandardItemModel; 8 class QMenu; 9 10 class ModelViewTable : public QWidget 11 { 12 Q_OBJECT 13 14 public: 15 ModelViewTable(QWidget *parent = Q_NULLPTR); 16 void generateDataSet(); 17 void addRowRecord(int row); 18 19 void setColumnItem(int row, int column, QString ip); 20 21 public slots: 22 void slotShowContextMenu(const QPoint& point); 23 private: 24 Ui::ModelViewTableClass ui; 25 QStandardItemModel * m_model; 26 QMenu* m_contextMenu; 27 }; 28 29 // ModelViewTable.cpp 30 #include "ModelViewTable.h" 31 32 #include 33 #include 34 #include 35 #include 36 #include 37 38 #include "CustomStandardItem.h" 39 40 ModelViewTable::ModelViewTable(QWidget *parent) 41 : QWidget(parent) 42 { 43 ui.setupUi(this); 44 45 //////////////////////////设置表头///////////////////// 46 m_model = new QStandardItemModel(this); 47 m_model->setColumnCount(3); 48 m_model->setHeaderData(0, Qt::Horizontal, QStringLiteral("终端IP")); 49 m_model->setHeaderData(1, Qt::Horizontal, QStringLiteral("CPU使用率")); 50 m_model->setHeaderData(2, Qt::Horizontal, QStringLiteral("内存使用率")); 51
52 ui.tableView->resizeColumnsToContents(); // 自适应列宽 53 ui.tableView->setSortingEnabled(true); // 可以按列来排序 54 ui.tableView->setModel(m_model); 55 ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter); 56 ui.tableView->horizontalHeader()->setFont(QFont("Times",10,QFont::Bold)); 57
58 ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中 59 ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);// 表格单元格为只读 60 ui.tableView->setContextMenuPolicy(Qt::CustomContextMenu); // 可以自定义右键菜单 61 62 m_contextMenu = new QMenu(this); 63 QAction *processAct = new QAction(QStringLiteral("进程列表信息"),m_contextMenu); 64 QAction *windowAppsAct = new QAction(QStringLiteral("窗口应用列表信息"),m_contextMenu); 65 m_contextMenu->addAction(processAct); 66 m_contextMenu->addAction(windowAppsAct); 67 68 connect(ui.tableView, SIGNAL(customContextMenuRequested(const QPoint&)), 69 this, SLOT(slotShowContextMenu(const QPoint&))); 70
71 72 } 73 74 void ModelViewTable::generateDataSet() 75 { 76 for (int i = 0; i < 3000; ++i) 77 { 78 addRowRecord(i); 79 } 80 } 81 82 void ModelViewTable::addRowRecord(int row) 83 { 84 // 每行3列 85 QString ip = QString("%1.%2.%3.%4").arg(192).arg(168).arg(1).arg(row); 86 setColumnItem(row, 0, ip); 87 88 QString cpu = QString("%1").arg((row * 10) % 100); 89 setColumnItem(row, 1, cpu); 90 91 QString mem = QString("%1").arg((row * 12) % 100); 92 setColumnItem(row, 2, mem); 93
94 } 95 96 void ModelViewTable::slotShowContextMenu(const QPoint& point) 97 { 98 QModelIndex index = ui.tableView->indexAt(point); 99 if (index.isValid()) 100 { 101 m_contextMenu->exec(QCursor::pos()); 102 } 103 } 104 105 void ModelViewTable::setColumnItem(int row, int column, QString ip) 106 { 107 m_model->setItem(row, column, new CustomStandardItem(ip)); 108 m_model->item(row, column)->setTextAlignment(Qt::AlignCenter); 109 }

Qt5中表格处理大数据量

因为需要实现自定义的数值排序,所以要继承QStandardItem,并覆盖其中的相关函数:

Qt5中表格处理大数据量

1 // CustomStandardItem.h 2 #pragma once 3 4 #include 5 #include 6 7 // 自定义数值排序 8 class CustomStandardItem : public QStandardItem 9 { 10 // Q_OBJECT 11 12 public: 13 CustomStandardItem(); 14 CustomStandardItem(const CustomStandardItem& other); 15 CustomStandardItem(const QString &text); 16 CustomStandardItem & operator =(const CustomStandardItem& other); 17 CustomStandardItem(); 18 19 public: 20 virtual bool operator<(const QStandardItem& other) const override; 21 22 }; 23 24 //CustomStandardItem.cpp 25 #include "CustomStandardItem.h" 26 27 #include 28 29 CustomStandardItem::CustomStandardItem() 30 { 31 } 32 33 CustomStandardItem::CustomStandardItem(const CustomStandardItem& other) 34 :QStandardItem(other) 35 { 36 37 } 38 39 CustomStandardItem::CustomStandardItem(const QString &text) 40 :QStandardItem(text) 41 { 42 43 } 44 45 CustomStandardItem::CustomStandardItem() 46 { 47 } 48 49 CustomStandardItem & CustomStandardItem::operator=(const CustomStandardItem& other) 50 { 51 QStandardItem::operator=(other); 52 return *this; 53 } 54 55 bool CustomStandardItem::operator<(const QStandardItem& other) const 56 { 57 const QVariant left = data(Qt::DisplayRole), right = other.data(Qt::DisplayRole); 58 // 第1到2列,全部采用浮点数的大小排序 59 if (column() == other.column() && other.column() >= 1 && other.column() <= 2) 60 { 61 return left.toDouble() < right.toDouble(); 62 } 63 64 return QStandardItem::operator<(other); 65 }

Qt5中表格处理大数据量

以上代码就完全实现了Model/View 的Table编程。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这