c++qtabstract-classqabstractlistmodel

Large set of data in QTableView


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.


Solution

  • 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);