Search code examples
c++qtqstandarditemmodel

QStandardItemModel: any efficient way to add rows?


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?


Solution

  • 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.