[Solved]View not updating when data changed



  • I'm making my first attempt at a model/view implementation in Qt, and I'm having difficulty getting my view to update when the data model changes.

    I Have a model that extends QAbstractTableModel and stores its information in a QList<QFileInfo>

    The model class has a method,

    @void FileListItemModel::setFiles(QStringList files)@

    which I call to update my data.

    After I have updated the data, i emit dataChanged.

    @void FileListItemModel::setFiles(QStringList files)
    {
    qDebug() << "setFiles";

    fileInfoList.clear();
    for ( int i=0; i<files.length(); ++i )
    {
        qDebug() << "file[" << i<<"]  " << files[i];
        fileInfoList.append( QFileInfo( files[i] ) );
    }
    emit dataChanged(QAbstractItemModel::createIndex(0,0), QAbstractItemModel::createIndex(2, files.length()-1));
    

    }@

    In my view class, i connect to the dataChanged signal just to check if its getting emited..

    @void FileListWidget::setModel(FileListItemModel *model)
    {
    ui->tableView->setModel(model);
    connect( model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(recognizeDataChanged(QModelIndex,QModelIndex)) );
    }@

    and my little recognizeDataChanged debug method is never called..

    @void FileListWidget::recognizeDataChanged(QModelIndex i1, QModelIndex i2)
    {
    qDebug() << "dataChanged dude";
    }@

    Am I not properly sending the dataChanged signal, or what else might I be doing incorrectly?



  • Hi!
    When you add new rows to the model use:
    @beginInsertRows();
    //Adding new rows
    endInsertRows();@

    when you remove rows:
    @beginRemoveRows();
    //Removing rows
    endRemoveRows();@

    in your case when you reload all data you can use(but not sure if this is correct):
    @beginResetModel();;
    //Removing rows
    endResetModel();;@

    Emitting dataChanged() useful if you change value of already existing item



    • the dataChanged signal should have the index of the values changed, given it index 0,0 will only update the first row, first column.
      Greetz


  • Hi, thanks for the reply..
    [quote author="qxoz" date="1360296348"]Hi!
    When you add new rows to the model use:
    @beginInsertRows();
    //Adding new rows
    endInsertRows();@

    when you remove rows:
    @beginRemoveRows();
    //Removing rows
    endRemoveRows();@

    in your case when you reload all data you can use(but not sure if this is correct):
    @beginResetModel();;
    //Removing rows
    endResetModel();;@

    Emitting dataChanged() useful if you change value of already existing item[/quote]

    I have tried both
    @beginInsertRows(QAbstractItemModel::createIndex(0,0),0,files.length());
    ...
    endInsertRows();@

    and
    @beginResetModel();
    ...
    endResetModel();@
    but neither seemed to have any effect.

    In this particular implementation I'm always replacing the entire data set, rather than adding an individual row to an existing data set.

    I was thinking that emit dataChanged would cause the data method of the model to be called over the range that had changed according to the emit dataChanged call, but both by putting some debugging output in the data method of my model, and the 'recognizeDataChanged' slot of my view, I can tell that this is not happening.



  • [quote author="Jeroentje@home" date="1360319105"]+ the dataChanged signal should have the index of the values changed, given it index 0,0 will only update the first row, first column.
    Greetz[/quote]

    Hi, I was thinking that
    emit dataChanged(QAbstractItemModel::createIndex(0,0), QAbstractItemModel::createIndex(2, files.length()-1));
    was saying that my entire data model changed, however I can see how how that wouldn't necessarily be accurate if I had reduced the number of items in my data model (which I wasn't expecting to happen, but nevertheless...)

    It seems like perhaps beginResetModel()/endResetModel() is the appropriate thing to do in that case, however I'm not seeing any effect as a result of using it. Perhaps I'm doing it wrong.
    @void FileListItemModel::setFiles(QStringList files)
    {
    beginResetModel();
    fileInfoList.clear();
    for ( int i=0; i<files.length(); ++i )
    {
    fileInfoList.append( QFileInfo( files[i] ) );
    }
    endResetModel();
    }@

    setFiles gets called, but my view never updates to reflect the new contents...



  • No surprise, it was a stupid problem... some bad code had me implicitly copying my model class over and over, so I was never updating the one associated with the view... Thanks for your help.


Log in to reply
 

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