I am trying to add large sets of data in QTableView. As there is huge set of data, in order to avoid freezing the application, I am trying to use a QAbstractTableModel
to not showthe whole dataset immediately, but only what is necessary. Based on the QT example for this (HERE), I have the following class:
FileListModel.cpp
#include "filelistmodel.h"
#include <QGuiApplication>
#include <QDir>
#include <QPalette>
#include "qdebug.h"
FileListModel::FileListModel(QObject *parent)
: QAbstractTableModel(parent), fileCount(0) //edit
{}
int FileListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : fileCount;
}
QVariant FileListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (index.row() >= fileList.size() || index.row() < 0)
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
return fileList.at(index.row());
}
return QVariant();
}
bool FileListModel::canFetchMore(const QModelIndex &parent) const
{
if (parent.isValid())
{
return false;
}
return (fileCount < fileList.size());
}
int FileListModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : colCount;
}
void FileListModel::fetchMore(const QModelIndex &parent)
{
if (parent.isValid())
{
return;
}
int remainder = fileList.size() - fileCount;
int itemsToFetch = qMin(100, remainder);
if (itemsToFetch <= 0)
{
return;
}
beginInsertRows(QModelIndex(), fileCount, fileCount + itemsToFetch - 1);
qDebug()<< "Qmodelindex "<< QModelIndex()<< "filecount "<< fileCount <<"filecount + itemtofetch "<<fileCount + itemsToFetch - 1;
fileCount += itemsToFetch;
endInsertRows();
}
void FileListModel::setColumnNumber(const int x) //edit
{
colCount = x;
}
void FileListModel::setDataToList(const QList<float> &data)
{
beginResetModel();
fileList = data;
fileCount = 0;
endResetModel();
}
FileListModel.h
#ifndef FILELISTMODEL_H
#define FILELISTMODEL_H
#include <QAbstractTableModel>
#include <QStringList>
class FileListModel : public QAbstractTableModel //edit
{
Q_OBJECT
public:
FileListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override; //edit
void setColumnNumber(const int );
public slots:
void setDataToList(const QList<float>&);
protected:
bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override;
private:
QList<float> fileList;
int fileCount;
int colCount;//edit
};
#endif // FILELISTMODEL_H
In my window, I have a QTableView
and 5 QList<float>
, each representing a column.
I proceed this way to add the data in my QTableView:
FileListModel *model=new FileListModel(this);
model->setColumnNumber(5); //edit
model->setDataToList(list1);
model->setDataToList(list2);
model->setDataToList(list3);
model->setDataToList(list4);
model->setDataToList(list5);
tableview->setModel(model)
However, the last list added (list5
) replace the previous one and I have only the same text in all the columns. I am aware that I need to write the needed code to add columns. But to be honest, I am not knowing very well the QAbstract
classes, and have no idea how to proceed. I would be grateful if you could provide me some hints or an example on how to modify my code in order to add columns in my model.
I found how to proceed by storing my data in a QList>. Please find below a working code that can probably be improved:
CPP FILE
#include "filelistmodel.h"
#include <QGuiApplication>
#include <QDir>
#include <QPalette>
#include "qdebug.h"
FileListModel::FileListModel(QObject *parent)
: QAbstractTableModel(parent), rowNumber(0)
{}
int FileListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : rowNumber;
}
int FileListModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : colNumber;
}
void FileListModel::setColumnNumber(const int x)
{
colNumber = x;
}
QVariant FileListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (index.row() >= fileList[0].size() || index.row() < 0)
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
return fileList[index.column()][index.row()];
}
return QVariant();
}
bool FileListModel::canFetchMore(const QModelIndex &parent) const
{
if (parent.isValid())
{
return false;
}
return (rowNumber < fileList[0].size());
}
void FileListModel::fetchMore(const QModelIndex &parent)
{
if (parent.isValid())
{
return;
}
int remainder = fileList[0].size() - rowNumber;
int itemsToFetch = qMin(100, remainder);
if (itemsToFetch <= 0)
{
return;
}
beginInsertRows(QModelIndex(), rowNumber, rowNumber + itemsToFetch - 1);
rowNumber += itemsToFetch;
endInsertRows();
}
void FileListModel::setDataToTable(const QList<QList<float>> &data)
{
beginResetModel();
fileList = data;
rowNumber = 0;
endResetModel();
}
H FILE
#ifndef FILELISTMODEL_H
#define FILELISTMODEL_H
#include <QAbstractListModel>
#include <QStringList>
class FileListModel : public QAbstractTableModel
{
Q_OBJECT
public:
FileListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void setColumnNumber(const int );
void setDataToTable(const QList<QList<float>>&);
protected:
bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override;
private:
QList<QList<float>> fileList;
int rowNumber;
int colNumber;
};
#endif // FILELISTMODEL_H
BUILDING MODEL
FileListModel *pModel =new FileListModel(this);
QList<QList<float>> a;
pModel->setColumnNumber(5);
a.append(qlist1);
a.append(qlist2);
a.append(qlist3);
a.append(qlist4);
a.append(qlist5);
pModel->setDataToTable(a);