Unsolved QStandardItem - checkbox - how to capture user change state?
-
Hey
I want to adjust what is happening when user click on checkbox on qstandarditem. I think its somehwere in mouseRelease event that it has to check if item.checkbox().contains(mouse->pos())(what I imagint it could look like) - but I can't find it in the source. Does any1 know where that check is being made?
Or maybe there is a better way to adjust the check signal to be sent to all selected items rather than just one? I want to bundle it up into a command to store undo data + change all selected items checkState if they contain that flag...
Thanks!
-
@Dariusz
You certainly do not want to approach this by tracking mouse position over checkbox in a mouse release event, and changing Qt source code! -
Hi,
What kind of action should happen when you check/uncheck your item ?
-
@SGaist He said:
Or maybe there is a better way to adjust the check signal to be sent to all selected items rather than just one?
-
@JNBarchan I know, but that's doesn't tell what is supposed to happen.
What are the selected item ?
How are they supposed to stay selected if there's a checkbox in an item that is clicked ?
etc. -
Well currently what I did is
testITem::mouseReleaseEvent(QMosueEvent *event){ QModelIndexList selectedLIst = selectedIndexes() QModelIndex clickedIndex = indexAt(event->pos()) QVariant oldItemState; // code here that checks the current item state QTreeView::mouseReleaseEvent(event) //code here that checks the "new" current item state and compares to oldItemState, if its different then it passes in loop below to selected items... loop over my selectedList{} and set their state to new state. }
I coded to check what was clicked and if the QCheckStateRole has changed of clicked item, then I loop over my indexes and do the same. Its a hax and I have 2 undo commands as 1 for clicked item and second for my list. I don't really like it but its the only way I could think of doing it. I think I'll try adjusting it so that my undo command - which now happens in model() - setData function will have a detection maybe to not generate undo command for checkbox and I'll handle that from treeClass or maybe move all to model not sure... its tricky.
@SGaist said in QStandardItem - checkbox - how to capture user change state?:
@JNBarchan I know, but that's doesn't tell what is supposed to happen.
What are the selected item ?
How are they supposed to stay selected if there's a checkbox in an item that is clicked ?
etc.I select 10 rows, and I click on checkbox in 1 of row, column 0. Then all selected rows, in column 0 should set their checkboxes to the one I clicked initially.
This is the result of my current "work around" not very proud of it tho... https://imgur.com/a/llOES
Edit. I just gave another look in to it, It Perhaps I found it, I previously looked in to qstandarditems and qabstractitemmodel/qabstractivemview etc but I didnt look in to tree view... looks like its the decoration > https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qtreeview.cpp.html#_ZN9QTreeView17mouseReleaseEventEP11QMouseEvent
Perhaps I can subclass that function - use source base and insert my loop there humhhhhhhh.....
to be precise:
if (d->itemDecorationAt(event->pos()) == -1) { 1901 QAbstractItemView::mouseReleaseEvent(event); getEvent signal/role/value -> apply to all selectedIndexes....humhhhhh how to get role/signal out of event :D
Nope, the last idea looks to be a bit of a headache to implement... I would have to reimplement half of source code :/
Need to reimplement itemDecorationAt() then itemDecorationRect() whhhh
-
Shouldn't you rather have a contextual menu with an entry like "Mark selected rows as check" or something like that ?
For me it would be counterintuitive that clicking on something in a table doesn't clear the current selection. It would also allow you to more cleanly handle undo/redo.
-
@SGaist said in QStandardItem - checkbox - how to capture user change state?:
Shouldn't you rather have a contextual menu with an entry like "Mark selected rows as check" or something like that ?
For me it would be counterintuitive that clicking on something in a table doesn't clear the current selection. It would also allow you to more cleanly handle undo/redo.
I find it more natural in my environment to have multiSelection checkbox update. I use few other apps and they all seems to have similar system implemented. Its just faster/easier. I'll see if I can fine tune my undo system to capture undo of checkboxes in that 1 location. Ahh hate it. I wanted to get all undo commands for treeView in 1 function, duh. Will come back to this issue when I have a "light bulp" :- )
Uh the table clear selection if you click on anything else but the checkbox.
-
@Dariusz
Even if you want to do this, I still don't get why you are choosing to approach it with such low-level stuff as mouse events and event position. I would handle theclicked
signal on the clicked row, and then something likesetCheckState()
on whatever other rows you also want? -
define a signal
Q_SIGNAL void checkChanged(const QModelIndex&);
Then use an additional role to store the previous value of
Qt::CheckStateRole
and compare itenum {ChStateChangedCheck = Qt::UserRole + Qt::CheckStateRole}; connect(model,&QAbstractItemModel::dataChanged,[=](const QModelIndex& topLeft, const QModelIndex& bottomRight)->void{ if(!topLeft.isValid()) return; Q_ASSERT(topLeft.model() == model); if(bottomRight.isValid()){ Q_ASSERT(bottomRight.model() == model); const auto parIdx = topLeft.parent(); Q_ASSERT(parIdx == bottomRight.parent()); for(int i=topLeft.row();i<=bottomRight.row();++i){ for(int j=topLeft.column();j<=bottomRight.column();++j){ const auto currIdx = model->data(i,j,parIdx); if(currIdx.data(ChStateChangedCheck) != currIdx.data(Qt::CheckStateRole)){ model->setData(currIdx,currIdx.data(Qt::CheckStateRole),ChStateChangedCheck); emit checkChanged(currIdx); } } } else{ if(topLeft.data(ChStateChangedCheck) != topLeft.data(Qt::CheckStateRole)){ model->setData(topLeft,topLeft.data(Qt::CheckStateRole),ChStateChangedCheck); emit checkChanged(topLeft); } } }
P.S. Could you please vote for this bug: https://bugreports.qt.io/browse/QTBUG-63766 as it's solution would transform your problem into just checking the 3rd argument of the
dataChanged
signal