QT tableview 实现千万数据加载,内存消耗小

QT tableview 实现千万数据加载,内存消耗小

最近在使用Dltview tool 观测MCU 的core 使用情况,发现DLTView tool 可以快速加载文件,tableview中显示的数据可以轻松达到千万级别

标题DLTview

从任务管理器中可以看出内存消耗 才500M

标题任务管理器

因为自己之前开发的工具也有类似的功能,但是效果没有这个好,于是研究了一下工具的源码,按照源码中的方法自己实验了一下tableview的用法。

实现这个功能的关键是要自己定义一个model 和tableview 空间关联上,在自定义的model中使用一个vector 的size 来记录 row 的大小。本例中使用QVector<qint64> *indexAll

#ifndef TABLEMODEL_H

#define TABLEMODEL_H

#include <QAbstractItemModel>

#include<QFile>

#include <QObject>

#include<QString>

class TableModel : public QAbstractTableModel

{

Q_OBJECT

public:

TableModel();

QVariant data(const QModelIndex &index, int role) const;

QVariant headerData(int section, Qt::Orientation orientation,

int role = Qt::DisplayRole) const;

int rowCount(const QModelIndex &parent = QModelIndex()) const;

int columnCount(const QModelIndex &parent = QModelIndex()) const;

void modelChanged();

void SetFile( QFile * _pfile, QVector<qint64> *pindexAll);

void setHorizontalHeaderLabels(const QStringList &labels);

private:

QStringList headerList;

QFile * pFile;

QVector<qint64> *indexAll;

};

#endif // TABLEMODEL_H

#include "tablemodel.h"

#include<QDebug>

TableModel::TableModel()

{

//headerList << tr("Name") << tr("Age") << tr("Gender");

pFile=nullptr;

}

QVariant TableModel::data(const QModelIndex &index, int role) const

{

if (!index.isValid() ||

(role != Qt::DisplayRole && role != Qt::EditRole)) {

return QVariant();

}

if (index.row() >= indexAll->size() && index.row()<0)

{

return QVariant();

}

//qDebug() << index.row()<< " "<<index.column();

long int filterposindex = 0;

filterposindex =index.row();

// qint64 positionForIndex=(*indexAll)[filterposindex];

// getmessage( index.row(), positionForIndex, &decodeflag, &msg, &lastmsg, pFile, &success);

switch(index.column())

{

case 0:

return QString("%L1").arg(filterposindex);

case 1:

return QString("%L1").arg((*indexAll)[filterposindex]);

case 2:

return QString("%L1").arg((*indexAll)[filterposindex]+1);

case 3:

return QString("%L1").arg((*indexAll)[filterposindex]+2);

}

return QVariant();

}

QVariant TableModel::headerData(int section, Qt::Orientation orientation,

int role) const

{

if (orientation == Qt::Horizontal) { //水平表头

if (role == Qt::DisplayRole) { //角色为显示

return headerList.at(section); //返回指定位置表头

}

}

return QAbstractTableModel::headerData(section, orientation, role);

}

int TableModel::rowCount(const QModelIndex &parent) const

{

if (parent.isValid()) {

return 0;

} else {

return indexAll->size(); //显示数据的大小

}

}

int TableModel::columnCount(const QModelIndex &parent ) const

{

if (parent.isValid()) {

return 0;

} else {

return headerList.size(); //表头的大小

}

}

void TableModel::modelChanged()

{

index(0, 1);

index(0, 0);

index(0, columnCount() - 1);

emit(layoutChanged());

}

void TableModel::SetFile( QFile * _pfile,QVector<qint64> *pindexAll)

{

pFile=_pfile;

indexAll=pindexAll;

}

void TableModel::setHorizontalHeaderLabels(const QStringList &labels) {

// qDebug() << PRETTY_FUNCTION;

if (!labels.empty())

headerList = labels;

}

#ifndef WORKTHREAD_H

#define WORKTHREAD_H

#include<QThread>

#include<QFile>

#include<QVector>

class WorkThread: public QThread

{

public:

WorkThread(QFile * _pfile, QVector<qint64> *pindexAll);

protected:

void run() override;

private:

QFile * pFile;

QVector<qint64> *indexAll;

};

#endif // WORKTHREAD_H

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

#include"tablemodel.h"

#include<QFile>

#include<QLabel>

#include"musicmodel.h"

#include <QTimer> //定时器类

#include<workthread.h>

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

MainWindow(QWidget *parent = nullptr);

~MainWindow();

private slots:

void on_pushButton_2_clicked();

void on_CreateData_clicked();

void on_actionLoadFile_triggered();

private:

Ui::MainWindow *ui;

TableModel * tableModel;

QFile outputfile;

QLabel *statusFilename;

QVector<qint64> indexAll;

WorkThread * pThread;

QTimer * timer;

};

#endif // MAINWINDOW_H

#include "workthread.h"

#include<QTime>

#include<QDebug>

#include <QtCore/QElapsedTimer>

WorkThread::WorkThread(QFile * _pfile, QVector<qint64> *pindexAll):pFile(_pfile),indexAll(pindexAll)

{

}

void WorkThread::run()

{

QElapsedTimer timer; //定义对象

timer.start(); //开始计时

for (int i = 0; i <10000000; i++)

{

QByteArray ba;

ba.resize(4);

ba[0] = (uchar)(0x000000ff & i);

ba[1] = (uchar)((0x0000ff00&i)>>8);

ba[2] = (uchar)((0x00ff0000&i)>>16);

ba[3] = (uchar)((0xff000000&i)>>24);

indexAll->push_back(i*4);

}

qDebug() << "The operation took" << timer.elapsed() << "milliseconds"; //显示结果

}

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include"dltfileutils.h"

#include<QDebug>

#include<QFileDialog>

#include <windows.h>

MainWindow::MainWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this);

statusFilename=new QLabel("No log file loaded");

statusFilename->setMinimumWidth(statusFilename->width());

//statusFilename->setMaximumWidth(statusFilename->width());

statusFilename->setMaximumWidth(1240);

// 640 is the initial width of the label

// but for some reason we need this for the very

// first call when setting the tempfile string

// unless this there are is displayed "..."

// more propper solution appreciated ...

statusFilename->setWordWrap(true);

statusBar()->addWidget(statusFilename,1);

QString fn = DltFileUtils::createTempFile(QDir ("."), false);

statusFilename->setText(fn);

statusFilename->setToolTip(fn);

outputfile.setFileName(fn);

outputfile.open(QIODevice::ReadWrite|QIODevice::Truncate);

tableModel =new TableModel;

tableModel->SetFile(&outputfile,&indexAll);

QStringList headerList;

headerList << tr("index") << tr("item1") << tr("item2")<< tr("item3")<< tr("item4");;

tableModel->setHorizontalHeaderLabels(headerList);

ui->tableView_3->setModel(tableModel);

ui->tableView_3->setSelectionBehavior(QAbstractItemView::SelectRows);

// ui->tableView_3->setSelectionMode(QAbstractItemView::SingleSelection);

ui->tableView_3->setEditTriggers(QAbstractItemView::NoEditTriggers);

ui->tableView_3->setStyleSheet("QHeaderView::section { background:green; color:white;min-height:3em;}");

ui->tableView_3->setGridStyle(Qt::SolidLine);

ui->tableView_3->horizontalHeader()->setStretchLastSection(true);

// ui->tableView_3->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

ui->tableView_3->verticalHeader()->setVisible(false);

timer = new QTimer(this);

//启动定时器

// timer->setSingleShot (true);

connect(timer,&QTimer::timeout,[=](){

tableModel->modelChanged();

// ui->tableView_3->scrollToBottom();

});

pThread = new WorkThread(&outputfile,&indexAll);

}

MainWindow::~MainWindow()

{

delete ui;

}

void MainWindow::on_pushButton_2_clicked()

{

// tableModel->removeColumns(0,1);

//tableModel->modelChanged();

}

void MainWindow::on_CreateData_clicked()

{

pThread->start();

// outputfile.close();

// qDebug()<<"size :"<<indexAll.size();

Sleep(100);

if(!timer->isActive())

timer->start(50);

}

void MainWindow::on_actionLoadFile_triggered()

{

QStringList fileNames = QFileDialog::getOpenFileNames(this,

tr("Open one or more DLT Log files"), "", tr("DLT Files (*.dlt);;All files (*.*)"));

if(fileNames.isEmpty())

return;

}

从log中看出来生成1千万数据耗时481毫秒

内存消耗186M


版权声明:本文为CSDN博主「cwei231」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/cwei231/article/details/131947874

相关推荐
我是黄大仙17 分钟前
利用飞书多维表格自动发布版本
运维·服务器·数据库·飞书
曾经的三心草17 分钟前
Mysql之约束与事件
android·数据库·mysql·事件·约束
WuMingf_25 分钟前
redis
数据库·redis
张某布响丸辣32 分钟前
SQL中的时间类型:深入解析与应用
java·数据库·sql·mysql·oracle
P.H. Infinity2 小时前
【RabbitMQ】10-抽取MQ工具
数据库·分布式·rabbitmq
zgscwxd2 小时前
thinkphp6 --数据库操作 增删改查
数据库·thinkphp6
代码小鑫2 小时前
A031-基于SpringBoot的健身房管理系统设计与实现
java·开发语言·数据库·spring boot·后端
天天要nx2 小时前
D64【python 接口自动化学习】- python基础之数据库
数据库·python
精进攻城狮@3 小时前
Redis(value的数据类型)
数据库·redis