Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Updating view with QAbstactTableModel



  • Hello. I'm subclassing QAbstractTableModel, reimlemented rowCount, columnCount, data, headerData. My model has class-container(Points points which has set<set<string>>) and method:

    const TableModel& TableModel::add(const string& s1, const string& s2, const string& s3 ) {
        auto info = points.prepare_for_add(s1, s2, s3); // first - index, where to put, second - true, if item already exist (update s2, s3)
        if (!info.second) {
            beginInsertRows(QModelIndex(), info.first, info.first);
            points.add(s1, s2, s3);
            endInsertRows();
        } else {
            points.add(s1, s2, s3);
            dataChanged(index(info.first, 0), index(info.first, 2));
        }
        return *this;
    }
    

    In mainWindow I have QTableView with my model, and button

    connect(loadbutton, &QPushButton::clicked,
      [=]() {
        for (...) {
          model->add(s1, s2, s3);
        }
    

    When i click button, new empty rows are adding until the end of a cycle, and only after the end of the cycle data appears. If I put view->update() after model->add(), everything is ok, rows are adding immediately with data. Can I somehow do this, without calling view->update()? Maybe I need to change my model->add, somehow? Am I using (begin/end)InsertRows() and dataChanged() right?



  • @Kot-Shrodingera

    Not sure what you mean by "until the end of a cycle". You add rows in a for loop, and I imagine the view does not get updated (visually) until that has finished. Inserting view->update() after each row add causes the visual updates to be seen immediately at that point.

    ?



  • @JonB yes, without view-update() only empty rows are added immediately. But after for cycle, when all empty rows have been added, data appears



  • @Kot-Shrodingera
    So it seems to me that is the way it works, and you have your optional workaround of explicitly calling view->update() if you want immediate visual feedback.



  • @Kot-Shrodingera said in Updating view with QAbstactTableModel:

    only empty rows are added immediately

    I'm surprised they are. I would have thought you'd need the control to go back to the event loop for anything on the screen to happen.

    You could replace:
    model->add(s1, s2, s3);
    with
    QMetaObject::invokeMethod(model,std::bind(&TableModel::add,model,s1,s2,s3),Qt::QueuedConnection);

    I don't know what string is in this context but you might need to declare and register it with Qt's meta object system


Log in to reply