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

QTableView Not Updating After Adding a New Row



  • Hey Folks

    Hope you all are doing Well.

    I have through a lot of similar links regarding the issue which I am getting on the Table view. Here's the code with its explanation :

    // Declared on the header file
    QStandardItemModel* model;
    
    // Intialization on Constructor
        model = new QStandardItemModel(0,0,this);
    
    // Here's the logic behind the view which I am showing on QsubWindow
    tableView = new QTableView(this);
        tableView->setModel(model);
        tableView->verticalHeader()->setVisible(false);
        tableView->verticalHeader()->setDefaultSectionSize(10);
    
        for(int i = 0; i < clusterNames.length(); i++) {
            QStandardItem *clusterName_i = new QStandardItem(clusterNames[i]);
            QStandardItem *clusterIP_i = new QStandardItem(clusterIPs[i]);
    
            model->setItem(i, 0, clusterName_i);
            model->setItem(i, 1, clusterIP_i);
        }
    
        tableView->viewport()->update();
    
        splitter = new QSplitter(this);
        splitter->setOrientation(Qt::Horizontal);
        splitter->addWidget(hwTreeContainer);
        splitter->addWidget(tableView);
    
    // Then I used to display it on the window which is basically a QsubWindow.
    

    Explanation: The Logic behind this is I am populating a dialog on the window and adding the details which are used to show on the table view. After closing that particular Qdialog I noticed that the new row has not been added to the Table View but if I reopen the window I see the updated view with updated rows on the table view.

    The issue I am getting is that my Table View isn't updating automatically after adding or inserting the new data. But if I reopen the same window then I see the updated things.

    If anyone could help me regarding this would be a great help.

    Thanks in Advance


  • Moderators

    @Satish-Joshi
    you initialize your model with no rows and no columns. Then you set the model to your view.
    The model never notifies the the view about a new row.

    so either you

    • initialize your model with the correct row & column count, or
    • call QStandardItemModel::insertRow() before your setItem() calls


  • void QStandardItemModel::appendRow(const QList<QStandardItem *> &items) is your friend Brother:

    for (int i = 0; i < clusterNames.length(); i++)
    {
        model->appendRow( { new QStandardItem(clusterNames[i]), new QStandardItem(clusterIPs[i]) } );
    }
    


  • @raven-worx

    First of all, Thank you so much for your time.

    As you mentioned that I am initializing the model with no rows and no columns. The reason behind it as I checked my model has updated data by debugging it but somehow it couldn't be able to show on the view.

    I also used QStandardItemModel::insertRow() in my code like this :

    model->insertRow(model->rowCount());
    
      for(int i = 0; i < clusterNames.length(); i++) {
          QStandardItem *clusterName_i = new QStandardItem(clusterNames[i]);
          QStandardItem *clusterIP_i = new QStandardItem(clusterIPs[i]);
    
          model->setItem(i, 0, clusterName_i);
          model->setItem(i, 1, clusterIP_i);
      }
    

    But sadly it didn't work or I am missing something. As I am calling the constructor of the current class (Where my logic has been there) after adding the new data which is in a different class of QDialog type. As I will share the glimpse of my QSubWindow type class constructor :

    HardwareDlg::HardwareDlg(QWidget *parent) :
        QMdiSubWindow(parent),
        ui(new Ui::HardwareDlg)
    {        
        this->setWindowTitle(HWWINDOW_NAME);
        this->resize(1200, 550);
    
        model = new QStandardItemModel(this);
    
        createActions();
        createMenus();
        newDeviceAct->setVisible(false);
        newDatagroupAct->setVisible(false);
        if (newMenu) {
            newMenu->setTitle("");
        }
    
        getClusterList();
        createStatusLabel();
        createMainView();  // This is the function which shows the data on table view and the main logic is written here
        createTreeView();
    }
    

    Also, I am attaching a screenshot so that it will briefer you :

    0_1561623982715_Cluster.png

    Please help me regarding this as I am stuck in this issue for like more than 2 days



  • @MasterBLB

    Thank You so much for your time brother.

    But sadly it didn't work. Actually, I want the view to update automatically after adding the new row through a dialog box. As I can see the changes if I reopen the particular window again.

    Also, my model has the updated data but somehow I don't know why table view is not updating.

    Thanks



  • Hmmm...try emit dataChanged(model->index(i, 0), model->index(i, 1), <maybe you'll have to pass 3rd parameter as well>) just after the line which adds new row.
    If that won't help then there are last resort methods - beginResetModel() before adding rows, and after completing add row operation endResetModel()
    Soo, merging my answers so far the output code would be:

    for (int i = 0; i < clusterNames.length(); i++)
    {
        model->appendRow( { new QStandardItem(clusterNames[i]), new QStandardItem(clusterIPs[i]) } );
        emit dataChanged(model->index(i, 0), model->index(i, 1));//maybe you'll have to pass 3rd parameter as well
    }
    

  • Moderators

    @Satish-Joshi said in QTableView Not Updating After Adding a New Row:

    Actually, I want the view to update automatically after adding the new row through a dialog box.

    i explained why it doesnt update.
    What exactly have you tried?!



  • @raven-worx

    Yes I understand what you trying to explain and have used your suggested approach and
    I have used QStandardItemModel::insertRow(). But it didn't work.

    Thanks



  • @MasterBLB

    you mean to say QAbstractItemModel::dataChanged(.....) right?

    I did it like this way :

    // In header File
    signals:
        void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
    
    // On the Loop
    emit model->dataChanged(model->index(i, 0), model->index(i, 1));
    

    Sorry but this time it also didn't work or I am missing something. Please let me know

    Thanks


  • Moderators

    @Satish-Joshi
    you are not doing what i suggested.
    Try this:

    model = new QStandardItemModel(this);
    model->setColumnCount( 2 );
    //...
    for(int i = 0; i < clusterNames.length(); i++)
    {
            QStandardItem *clusterName_i = new QStandardItem(clusterNames[i]);
            QStandardItem *clusterIP_i = new QStandardItem(clusterIPs[i]);
            model->appendRow( QList<QStandardItem*>() << clusterName_i << clusterIP_i );
    }
    


  • @raven-worx

    Sorry. It didn't work though

    I think there might be some issue with Widget or QSubWindow because as I already mentioned that the values are already updating on the model (checked through debugging it) but couldn't be displayed on the View.

    As if I reopen the window it displays properly.

    What do you think?

    Thanks Anyway



  • Use that beginResetModel() and endResetModel() methods then, these makes a model completely invalidated, and therefore force a thorough update.

    model->beginResetModel();
    for (int i = 0; i < clusterNames.length(); i++)
    {
        model->appendRow( { new QStandardItem(clusterNames[i]), new QStandardItem(clusterIPs[i]) } );  
    }
    model->endResetModel();
    


  • @MasterBLB

    It seems both are protected members so can't access through it.

    Thanks



  • Inherit QStandardItemModel, and declare public functions like beginReset() and endReset() whose internally invoke these protected methods.


Log in to reply