Important: Please read the Qt Code of Conduct -

update QTableView from QAbstractTableModel with dataChanged()???

  • I have a QTableView and i have set as its model a class inherited from QAbstractTableModel. I have implemented the proper rowCount(),columnCount(),data() virtual methods that are need for a proper TableModel.

    So my question is this. When the data in the model changes how can I tell the QTableView to update itself?

    I looking through documentation is found that i should emit the signal dataChanged()... but i dont see what slot on the table view i should connect this to. I dont even see a slot on tableview that has the same parameters..

    here is the method that i emit data changed in

    void signalTapSignalAggregator::updateFinished(){
         QModelIndex topLeft = index(0, 0);
         QModelIndex bottomRight = index(numberOfRow, listOfSignals.size());
         //emit  layoutAboutToBeChanged();
         emit layoutChanged();
         emit dataChanged(topLeft,bottomRight);

    now after i emit layoutChanged() it seems that the tableview update the number of columns that are needed but there is no data in them.

    i have set a break point on data() method of the model in hopes that I will see the QTableView attempt to read the new data but it never fires after i call dataChanged()

    So how do i connect the dataChanged() signal to the QTableView????

  • Lifetime Qt Champion


    You don't have to, it's internally done.

    Why are you calling beginResetModel ? You are not reseting it and if you call any of the beginXXX method you also have to call the matching endXXX method.

  • i dont know why i was calling dataChanged() to be honest... i was flailing around trying to get the table to update and i left this in there...

    Ok so they are connected internally.. that is kinda what i suspected, but its good to know for sure.

    So after the the dataChanged() signal is emit what is the TableView supposed to do in response? I was expecting the TableView to try to use the data() method in the model to read that updated data, bit its not calling this method after I emit dataChanged()...

    thanks for you reply.

  • Lifetime Qt Champion

    Did you check that bottomRight is a valid index ?

  • i didn't explicitly do this, but i did try setting the bottom right to (1,1) thinking that this would be a valid index but still no change...

    I was just looking at the address book example

    and i noticed that they implement they setRows,setData functions and this is where the dataChanged() signal is emitted....

    in my example I am not doing this...

    my reasoning was that i dont need the model to be "editable" from the view... rather the data in the model is initialed once the user imports a file...

    so my question is this... do i need to implement the setData and setRow methods... een though i dont want the model to be editable from the view... rather i want it to change based on some external source???

    i think the ansewr is yes and i need to go do that....

  • Lifetime Qt Champion

    setData is used when you edit your model through a view so no, you don't need to implement it if your view is going to be read-only.

    You have to emit dataChanged when you modify the content of your model be it through setData or other means.

    If you change the geometry of the model you have to call the beginXXX/endXXX before emitting dataChanged.

  • hmm. that is good to know.

    i am chaning the geoemetries.... that is probably what i am doing wrong... what function are the XXX refering to? the beginInsertRows()?? beginInsertColumns()???

    i think i was naively assuming that as long as i implemented rowCount() and columnCount() i would be ok

    but even if i did that shouldn't the view attempt to ready new data from the model through the data() function after i emit data dataChanged()???

  • Lifetime Qt Champion

    rowCount and columnCount are only getters. You have to notify the view that something is changing, that's the use of beginInsertXXX/endInsertXXX. You notify the view that e.g. the row count is about to change, then you do the actual changes and at the end you notify the view that it's OK for it to refresh itself with the new content.

Log in to reply