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

How to properly loop over QAbstractItemModel->setData() ?



  • I have a QTableView called mytableview and I want to change the first column of selected rows to "disabled" upon a mouseclick.
    Here is the function called when the respective button is clicked:

    void TableTab::ignore_clicked(){
    
        QItemSelectionModel *myselectionmodel = mytableview->selectionModel();
        QModelIndexList myselectedrows = myselectionmodel->selectedRows(); 
        QModelIndex index;
    
        for(int i=0; i<myselectedrows.size(); i++){
           index = myselectedrows.at(i);
           mytableview->model()->setData(index, "disabled");
        }
    
    }
    

    This however does not change all the selected rows but only the first selected row. I assume I am somehow doing the looping wrong because after the first loop mytableview->model()->setData() returns false instead of true. How am I doing this properly?



  • If it's a table and not a tree, try like this:

    QModelIndexList myselectedIdx = mytableview->selectionModel()->selectedIndexes();
    std::sort(myselectedIdx.begin(),myselectedIdx.end(),[](const QModelIndex& a, const QModelIndex& b)->bool{return a.row()<b.row();});
    auto model = mytableview->model();
    model->setData(model->index(myselectedIdx.first().row(),0),QStringLiteral("disabled"));
    for(auto i = myselectedIdx.cbegin()+1;i!=myselectedIdx.cend();++i){
    if(i->row()==(i-1)->row()) continue;
    model->setData(model->index(i->row(),0),QStringLiteral("disabled"));
    }
    


  • Unfortunately this is no different to my solution. It still only changes the first selected row.



  • what is the model?



  • Which model do you mean?
    The table-model is an QSqlTableModel based on QSqlDatabase



  • Very strange.
    Could you use the code below and tell me what gets printed out to console?

    QModelIndexList myselectedIdx = mytableview->selectionModel()->selectedIndexes();
    std::sort(myselectedIdx.begin(),myselectedIdx.end(),[](const QModelIndex& a, const QModelIndex& b)->bool{return a.row()<b.row();});
    auto model = mytableview->model();
    model->setData(model->index(myselectedIdx.first().row(),0),QStringLiteral("disabled"));
    for(auto i = myselectedIdx.cbegin()+1;i!=myselectedIdx.cend();++i){
    if(i->row()==(i-1)->row()) continue;
    qDebug() << i->row();
    model->setData(model->index(i->row(),0),QStringLiteral("disabled"));
    }
    


  • When selecting the first five rows:
    1
    2
    3
    4



  • so it's correct, it's just setData that is failing. Try this:

    QModelIndexList myselectedIdx = mytableview->selectionModel()->selectedIndexes();
    if(!myselectedIdx.isEmpty()){
    std::sort(myselectedIdx.begin(),myselectedIdx.end(),[](const QModelIndex& a, const QModelIndex& b)->bool{return a.row()<b.row();});
    auto model = qobject_cast<QSqlTableModel*>(mytableview->model());
    Q_ASSERT(model);
    const auto oldStrategy = model->editStrategy();
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    Q_ASSUME(model->setData(model->index(myselectedIdx.first().row(),0),QStringLiteral("disabled")));
    for(auto i = myselectedIdx.cbegin()+1;i!=myselectedIdx.cend();++i){
    if(i->row()==(i-1)->row()) continue;
    Q_ASSUME(model->setData(model->index(i->row(),0),QStringLiteral("disabled")));
    }
    Q_ASSUME(model->submitAll());
    model->setEditStrategy(oldStrategy);
    }
    


  • Although I still don't understand why setData returns false after the first selected row, this works. Thank you!


Log in to reply