Qt5中表格处理大数据量
在Qt中如果是普通项目,GUI处理展现的数据量不大,一般用QTableWidget,QTreeWidget这样的控件就满足了,但是如果数据量行数达到了几万行,那么Widget的展示性能就偏差了。
Qt中提供了一种Model/View的编程方式来处理数据,也就是展示层和数据层分离,这样就解耦了。一旦Model的状态改变,它会自动渲染到View控件。这样的机制使得GUI可以展现大量的数据也不会卡顿。
为了处理数据的灵活性,我们用QStandardItemModel来做QTableView的Model层实现。因为以Table的形式展现,所以以下代码实现了,点击表头按列排序,点击行显式行的上下文菜单的功能。因为QTableView的默认
排序是按字符序列排序,所以得对QStandardItem进行子类化,并重载operator< 函数才能达到某些列用数值大小来排序。
因为是简单的Demo例子,QTableView是采用拖拽空间的方式拖到一个Widget里面的,该Wdiget类为ModelViewTable:
// ModelViewTable.h
#pragma once #include <QtWidgets/QWidget>
#include "ui_ModelViewTable.h" class QStandardItemModel;
class QMenu; class ModelViewTable : public QWidget
{
Q_OBJECT public:
ModelViewTable(QWidget *parent = Q_NULLPTR);
void generateDataSet();
void addRowRecord(int row); void setColumnItem(int row, int column, QString ip); public slots:
void slotShowContextMenu(const QPoint& point);
private:
Ui::ModelViewTableClass ui;
QStandardItemModel * m_model;
QMenu* m_contextMenu;
}; // ModelViewTable.cpp
#include "ModelViewTable.h" #include <QStandardItemModel>
#include <QStandardItem>
#include <QString>
#include <QMenu>
#include <QAction> #include "CustomStandardItem.h" ModelViewTable::ModelViewTable(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this); //////////////////////////设置表头/////////////////////
m_model = new QStandardItemModel(this);
m_model->setColumnCount();
m_model->setHeaderData(, Qt::Horizontal, QStringLiteral("终端IP"));
m_model->setHeaderData(, Qt::Horizontal, QStringLiteral("CPU使用率"));
m_model->setHeaderData(, Qt::Horizontal, QStringLiteral("内存使用率")); ui.tableView->resizeColumnsToContents(); // 自适应列宽
ui.tableView->setSortingEnabled(true); // 可以按列来排序
ui.tableView->setModel(m_model);
ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);
ui.tableView->horizontalHeader()->setFont(QFont("Times",,QFont::Bold)); ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中
ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);// 表格单元格为只读
ui.tableView->setContextMenuPolicy(Qt::CustomContextMenu); // 可以自定义右键菜单 m_contextMenu = new QMenu(this);
QAction *processAct = new QAction(QStringLiteral("进程列表信息"),m_contextMenu);
QAction *windowAppsAct = new QAction(QStringLiteral("窗口应用列表信息"),m_contextMenu);
m_contextMenu->addAction(processAct);
m_contextMenu->addAction(windowAppsAct); connect(ui.tableView, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(slotShowContextMenu(const QPoint&))); } void ModelViewTable::generateDataSet()
{
for (int i = ; i < ; ++i)
{
addRowRecord(i);
}
} void ModelViewTable::addRowRecord(int row)
{
// 每行3列
QString ip = QString("%1.%2.%3.%4").arg().arg().arg().arg(row);
setColumnItem(row, , ip); QString cpu = QString("%1").arg((row * ) % );
setColumnItem(row, , cpu); QString mem = QString("%1").arg((row * ) % );
setColumnItem(row, , mem); } void ModelViewTable::slotShowContextMenu(const QPoint& point)
{
QModelIndex index = ui.tableView->indexAt(point);
if (index.isValid())
{
m_contextMenu->exec(QCursor::pos());
}
} void ModelViewTable::setColumnItem(int row, int column, QString ip)
{
m_model->setItem(row, column, new CustomStandardItem(ip));
m_model->item(row, column)->setTextAlignment(Qt::AlignCenter);
}
因为需要实现自定义的数值排序,所以要继承QStandardItem,并覆盖其中的相关函数:
// CustomStandardItem.h
#pragma once #include <QStandardItem>
#include <QString> // 自定义数值排序
class CustomStandardItem : public QStandardItem
{
// Q_OBJECT public:
CustomStandardItem();
CustomStandardItem(const CustomStandardItem& other);
CustomStandardItem(const QString &text);
CustomStandardItem & operator =(const CustomStandardItem& other);
~CustomStandardItem(); public:
virtual bool operator<(const QStandardItem& other) const override; }; //CustomStandardItem.cpp
#include "CustomStandardItem.h" #include <QVariant> CustomStandardItem::CustomStandardItem()
{
} CustomStandardItem::CustomStandardItem(const CustomStandardItem& other)
:QStandardItem(other)
{ } CustomStandardItem::CustomStandardItem(const QString &text)
:QStandardItem(text)
{ } CustomStandardItem::~CustomStandardItem()
{
} CustomStandardItem & CustomStandardItem::operator=(const CustomStandardItem& other)
{
QStandardItem::operator=(other);
return *this;
} bool CustomStandardItem::operator<(const QStandardItem& other) const
{
const QVariant left = data(Qt::DisplayRole), right = other.data(Qt::DisplayRole);
// 第1到2列,全部采用浮点数的大小排序
if (column() == other.column() && other.column() >= && other.column() <= )
{
return left.toDouble() < right.toDouble();
} return QStandardItem::operator<(other);
}
以上代码就完全实现了Model/View 的Table编程。
references:
https://stackoverflow.com/questions/18421603/displaying-big-data-using-qt-table-view
https://stackoverflow.com/questions/4031168/qtableview-is-extremely-slow-even-for-only-3000-rows
https://doc.qt.io/archives/qq/qq07-big-tables.html
http://blog.csdn.net/woshiwlia/article/details/9141065
http://blog.csdn.net/u013255206/article/details/62235052
http://qimo601.iteye.com/blog/1539147
http://qimo601.iteye.com/blog/1530539
http://qimo601.iteye.com/blog/1530245
Qt5中表格处理大数据量的更多相关文章
- [C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案
1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本 ...
- jquery.datatable.js与CI整合 异步加载(大数据量处理)
http://blog.csdn.net/kingsix7/article/details/38928685 1.CI 控制器添加方法 $this->show_fields_array=arra ...
- J2EE综合:如何处理大数据量的查询
在实际的任何一个系统中,查询都是必不可少的一个功能,而查询设计的好坏又影响到系统的响应时间和性能这两个要害指标,尤其是当数据量变得越来越大时,于是如何处理大数据量的查询成了每个系统架构设计时都必须面对 ...
- asp.net中绘制大数据量的可交互的图表
在一个asp.net项目中要用到能绘制大数据量信息的图表,并且是可交互的(放大.缩小.导出.打印.实时数据),能够绘制多种图形. 为此进行了多方调查预研工作,预研过微软的MsChart图表组件.基于j ...
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...
- 大数据量表中,增加一个NOT NULL的新列
这次,发布清洗列表功能,需要对数据库进行升级.MailingList表加个IfCleaning字段,所有的t_User*表加个IfCleaned字段. 脚本如下 对所有的t_User表执行 a ...
- C# & SQL Server大数据量插入方式对比
以下内容大部分来自: http://blog.csdn.net/tjvictor/article/details/4360030 部分内容出自互联网,实验结果为亲测. 最近自己开发一个向数据库中插入大 ...
- MySQL数据库如何解决大数据量存储问题
利用MySQL数据库如何解决大数据量存储问题? 各位高手您们好,我最近接手公司里一个比较棘手的问题,关于如何利用MySQL存储大数据量的问题,主要是数据库中的两张历史数据表,一张模拟量历史数据和一张开 ...
- DB开发之大数据量高并发的数据库优化
一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...
随机推荐
- Go语言之进阶篇简单版并发服务器
1.简单版并发服务器 示例1: package main import ( "fmt" "net" "strings" ) //处理用户请求 ...
- PHP操作数据库函数比较
常用的php语法连接mysql如下 <?php $link = mysql_connect('localhost', 'user', 'password'); mysql_select_db(' ...
- Mysql 创建表时错误:Tablespace for table `tablexx` exists. Please DISCARD the tablespace before IMPORT.
在本地的一个数据库创建表时意外的出现了以下错误,说是表已经存在了 但通过desc 查看表信息时又说表不存在 在本地系统搜索表名却发现一个.ibd文件[InnoDB File] 在删除了该.ibd文件文 ...
- free的说明
http://www.cnblogs.com/peida/archive/2012/12/25/2831814.html
- (转)Unity3D研究院之IOS&Android收集Log文件
转自:http://www.xuanyusong.com/archives/2477 有段时间没有写过文章了,不知道大伙儿还记得雨松MOMO吗? 嘿嘿. 开发项目的时候尤其在处理与服务器交互这块,如果 ...
- Effective JavaScript Item 63 注意异步调用中可能会被忽略的异常
异常处理是异步编程的一个难点. 在同步的代码中,异常可以非常easy地通过try catch语句来完毕: try { f(); g(); h(); } catch (e) { // handle an ...
- win8下everything无法使用的解决方法
今日我电脑上的Everything打开后都无法使用了,只显示几个分区,重装之后暂时就好了,重启电脑又坏了 解决方法:运行services.msc,启动everything.然后重启everything ...
- OpenGL ES 3.0之Uniform详解
Uniform是变量类型的一种修饰符,是OpenGL ES 中被着色器中的常量值,使用存储各种着色器需要的数据,例如:转换矩阵.光照参数或者颜色. uniform 的空间被顶点着色器和片段着色器分享 ...
- 安装ecshop2.7时候的错误处理 php版本不兼容引起
装ECShop2.7.3出现了一堆问题,主要是因为PHP版本过高引起的,不愿意降低版本,则只能一个个解决啦!这些问题包括:preg_replace.cls_image::gd_version.end( ...
- linux安装experss搭建本地服务器
准备nodejs和npm 保证本地安装了nodeJS和npm,如果没有安装的话,通过下面的命令进行安装: sudo apt-get install nodejs //安装nodeJS sudo apt ...