How to properly loop over QAbstractItemModel->setData() ?
-
wrote on 7 Jan 2020, 13:45 last edited by
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?
-
wrote on 7 Jan 2020, 15:45 last edited by
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")); }
-
wrote on 7 Jan 2020, 16:01 last edited by
Unfortunately this is no different to my solution. It still only changes the first selected row.
-
wrote on 7 Jan 2020, 16:02 last edited by
what is the model?
-
wrote on 7 Jan 2020, 16:14 last edited by
Which model do you mean?
The table-model is an QSqlTableModel based on QSqlDatabase -
wrote on 7 Jan 2020, 16:16 last edited by
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")); }
-
wrote on 7 Jan 2020, 16:27 last edited by
When selecting the first five rows:
1
2
3
4 -
wrote on 7 Jan 2020, 17:08 last edited by VRonin 1 Aug 2020, 09:26
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); }
-
wrote on 8 Jan 2020, 08:02 last edited by
Although I still don't understand why setData returns false after the first selected row, this works. Thank you!
1/9