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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.