Can't edit text in cell in a dynamic QTable model



  • Hello, I am in troubles with my model, I have created a model where I can dinamically add new rows, then I want to edit its text, so I created a vector in my class such as I can dinamically add or modify text, but I obtain the following error:

    ASSERT failure in QVector<T>::operator[]: "index out of range", file /Users/aaaa/Qt/5.11.1/clang_64/lib/QtCore.framework/Headers/qvector.h, line 436
    19:54:10: The program has unexpectedly finished.

    bool Table::setData(const QModelIndex & index, const QVariant & value, int role)
    {
         m_gridData = new QVector<QVector<QString>>;
    
        if (role == Qt::EditRole)
        {
            //save value from editor to member m_gridData
            (*m_gridData)[index.row()][index.column()]= value.toString();
            //for presentation purposes only: build and emit a joined string
            QString result;
            for(int row= 0; row < rows; row++)
            {
                for(int col= 0; col < columns; col++)
                {
                    result += (*m_gridData)[row][col];
    
                }
            }
            emit editCompleted(result);
            return true;
        }
        return false;
    }
    

    Why is my index out of range??

    Thank you!


  • Lifetime Qt Champion

    Hi
    The vector is empty so accessing it will crash.
    [index.row()][index.column()] can never be valid for empty vector.

    if you want to use [][], you should use
    https://doc.qt.io/qt-5/qvector.html#reserve
    https://doc.qt.io/qt-5/qvector.html#resize
    on both vectors.
    so they contain empty strings.
    Or use append to add the data.



  • You mean change
    (*m_gridData)[index.row()][index.column()]= value.toString();

    By
    (*m_gridData)[row][column]= value.toString();???


  • Qt Champions 2018

    Again: you can't access to an index which is out-of-bounds and will get an asserting (in debug mode) or undefined behavior (in release mode) - see https://doc.qt.io/qt-5/qvector.html#operator-5b-5d

    "i must be a valid index position in the vector (i.e., 0 <= i < size())."


  • Qt Champions 2018

    Memory Leaks Everywhere

    Why are you doing m_gridData = new QVector<QVector<QString>>;?



  • I tried this

    bool ModelTable::setData(const QModelIndex & index, const QVariant & value, int role)
    {
        m_gridData = new QVector<QVector<QString>>;
    
    
        if (role == Qt::EditRole)
        {
            //save value from editor to member m_gridData
            (*m_gridData)[index.row()][index.column()]= value.toString();
    
            //for presentation purposes only: build and emit a joined string
    
            QString result;
            for(int row= 0; row < rows; row++)
            {
                for(int col= 0; col < columns; col++)
                {
                    //result += (*m_gridData)[row][col];
                    (*m_gridData).append(QVector<QString>()<<result);
    
                }
            }
            emit editCompleted(result);
            return true;
        }
        return false;
    }
    
    

    and Initialized the vector in constructor such as:

    ModelTable::ModelTable(QObject *parent):QAbstractTableModel (parent)
    {
     m_gridData = new QVector<QVector<QString>>;
    }
    

    and updated size such as:

    bool ModelTable::insertRows(int row, int count, const QModelIndex &parent){
        beginInsertRows(parent,row,row+count-1);
        rows = rows+count;
        endInsertRows();
        qDebug() << rows;
         (*m_gridData)[rows][columns];//update value of matrix
        return true;
    

    and still index out of range.

    I did this
    (*m_gridData)[index.row()][index.column()]= value.toString();
    to store the initial values of table into my m_gridData and update them as the programs is working.

    Thanks!


  • Qt Champions 2018

    None of the above makes any sense.

    Why are you subclussing a model anyway? What is the problem with just using QStandardItemModel?



  • Because I want it modified by adding new methods later associated with dynamic table. What I wish is to add dinamycally rows by pressing a button, then store data into cells and this data into a vector of vectors to be modified on execution time


  • Qt Champions 2018

    Everything you described can be done by QStandardItemModel.
    Something like:

    QAbstractItemModel* model = new QStandardItemModel(this);
    model->insertColumns(0,columns);
    model->insertRows(0,rows);
    model->setData(model->index(0,0),QStringLiteral("One String"));
    model->setData(model->index(1,0),QStringLiteral("Another String"));
    model->insertRow(1);
    model->setData(model->index(1,0),QStringLiteral("Inserted String"));
    

    @jss193 said in Can't edit text in cell in a dynamic QTable model:

    I want it modified by adding new methods later

    You can always just subclass QStandardItemModel you don't need to start from scratch


  • Lifetime Qt Champion

    Hi
    Besides i very much agree with @VRonin about using QStandardItemModel
    Your current issue is that you use 2 vectors now

    bool ModelTable::setData(const QModelIndex & index, const QVariant & value, int role)
    {
    m_gridData = new QVector<QVector<QString>>; // this is a new one, you add to
    ...

    so
    the one you make
    ModelTable::ModelTable(QObject *parent):QAbstractTableModel (parent)
    {
    m_gridData = new QVector<QVector<QString>>;

    Might not be used at all and just leak memory or be used in
    bool ModelTable::insertRows where its empty and still gives index out of bounds for that reason.


Log in to reply