0

I have tried using Qt void QStandardItem::insertRow(int row, const QList<QStandardItem *> &items) and void QStandardItem::appendRow(const QList<QStandardItem *> &items) to dynamically add rows in my model. These take very less time for small number of rows. However, for large number of row entries, say 100,000, it takes way too long time.

I read this similar question but it was not very helpful. Is there any other way to do this more efficiently?

Rishu Singh
  • 49
  • 1
  • 11
  • 3
    write your own insert function with the help of `void QAbstractItemModel::beginInsertRows(const QModelIndex & parent, int first, int last)` `void QAbstractItemModel::endInsertRows()` and `void QAbstractItemModel::beginResetModel()` `void QAbstractItemModel::endResetModel()` – Eligijus Pupeikis Jan 31 '18 at 07:04
  • 4
    If you instead use QAbstractItemModel you have greater freedom to change how the model is populated. – user2672165 Jan 31 '18 at 07:11
  • Do you add entries one by one, or pass all the 100000 items in one time? – Dmitry Sazonov Jan 31 '18 at 07:47
  • @Dimitry I want to add it one by one – Rishu Singh Jan 31 '18 at 08:05
  • Your `QStandardItemModel` stores 100K objects, while models implemented as sub classes of `QAbstractItemModel` may contain no objects at all. This confirms what @user2672165 said in his/her comment. – vahancho Jan 31 '18 at 08:54

1 Answers1

1

Thanks to the comment section for pointing me in right direction, I was able to solve the problem myself.

I tried to implement a subclass of QAbstractItemModel. Given below is the implimnetation of bool QAbstractItemModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex()). This code just added blank cells in my GUI. The idea was just to check how fast the cells were added:

bool CustomTableModel::insertRows(int position, int rows, const QModelIndex &parent)
{
    beginInsertRows(parent, position, position + rows - 1);
    for (int row = 0; row < rows; row++) 
    {
        QStringList items;
        for (int column = 0; column < 7; ++column)// I required only 7 columns 
            items.append("");
        rowList.insert(position, items); // QList<QStringList> rowList;
    }
    endInsertRows();
    return true;
}

This approach increased the overall performance of adding new rows. However, it was still not very fast for my requirement. It seems that QAbstractItemModel::beginInsertRows(const QModelIndex & parent, int first, int last) and QAbstractItemModel::endInsertRows() caused the overall bottleneck.

At the end, I just used the following constructor to create a table of sufficiently large number of rows:

CustomTableModel::CustomTableModel(int rows, int columns, QObject *parent): QAbstractTableModel(parent)
{
    QStringList newList;

        for (int column = 0; column < columns; column++) {
            newList.append("");
        }

        for (int row = 0; row < rows; row++) {
            rowList.append(newList); // QList<QStringList> rowList;
        }
}

Then I just created a custom function to insert the values in the cell:

void CustomTableModel::insertRowValues(int row,int col, QString val)
{
    rowList[row][col] = val;
}

Calling this function repeatedly to fill individual cells created the table surprisingly fast (or at least faster then earlier). This solution does not feel very elegant but it solved my problem.

Rishu Singh
  • 49
  • 1
  • 11
  • Actually, if the table content is never modified i.e. it should have all those rows from the start then inserting rows is not necessary. The view will ask for the content in each cell using the data(..) function given that you have specified rowCount() and columnCount(). – user2672165 Feb 09 '18 at 07:03
  • @ user2672165 I did realize this later upon further reading about QAbstractItemModel and model/view programming in general. However, being new to Qt framework, it took me a while to wrap my head around this topic. – Rishu Singh Feb 10 '18 at 03:33