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

文章介绍了如何使用QTtableview处理千万级别的数据,同时通过DLTViewtool观察内存使用,实现内存消耗保持在较低水平。作者分享了自定义TableModel的方法和关键代码片段,以展示如何有效管理内存和提高性能。
摘要由CSDN通过智能技术生成

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);
         //DU


         indexAll->push_back(i*4);//读到indexAll中
 
    }
    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值