QTreeView drop event & re-selecting dropped items
-
Hey @raven-worx
I don't use modelIndexes at all during my move. I just pass vector with pointers to myNodes directly. As you can see after I do the drop and items are in new location, I run void icTree::setSelectionOnDroppedItems(std::vector<myNodes*> _droppedNodes) {} which re-creartes QModelIndexes, As I said in the "//// PS" comment. the function selects everything correctly. But then QT runs something after dropEvent that messes up my selection. I cant track down what QT runs after event drop so I can stop that.
There must be a function that gets executed after void myTree::dropEvent(QDropEvent *event) {} that does something with the selection.
-
Hey @raven-worx
I don't use modelIndexes at all during my move. I just pass vector with pointers to myNodes directly. As you can see after I do the drop and items are in new location, I run void icTree::setSelectionOnDroppedItems(std::vector<myNodes*> _droppedNodes) {} which re-creartes QModelIndexes, As I said in the "//// PS" comment. the function selects everything correctly. But then QT runs something after dropEvent that messes up my selection. I cant track down what QT runs after event drop so I can stop that.
There must be a function that gets executed after void myTree::dropEvent(QDropEvent *event) {} that does something with the selection.
@Dariusz said in QTreeView drop event & re-selecting dropped items:
I don't use modelIndexes at all during my move. I just pass vector with pointers to myNodes directly
Then what does
QModelIndex itemIndex = _droppedNodes[x]->index();
exactly do? -
It creates new QModelIndexes for items after they were dropped. Sorry, I probably should not say that I don't use QModelIndexes at all. I use them but I create them after the items were dropped so they are all valid and correct. When I run this command
QCoreApplication::processEvents(); system("pause");
I can see all my dragged items being selected = great, but after that QT somehow breaks selection. No idea why and where. :- (!
PS I have recorded a gif with the function above(processEvents and pause to show the issue)
https://pasteboard.co/HaOlUyz.gifPS2 it feels to me that when I EnterDropEvent, a selection state is somewhere stored, and after I finish drop, that selection state is being restored. But I cant figure out where.
-
It creates new QModelIndexes for items after they were dropped. Sorry, I probably should not say that I don't use QModelIndexes at all. I use them but I create them after the items were dropped so they are all valid and correct. When I run this command
QCoreApplication::processEvents(); system("pause");
I can see all my dragged items being selected = great, but after that QT somehow breaks selection. No idea why and where. :- (!
PS I have recorded a gif with the function above(processEvents and pause to show the issue)
https://pasteboard.co/HaOlUyz.gifPS2 it feels to me that when I EnterDropEvent, a selection state is somewhere stored, and after I finish drop, that selection state is being restored. But I cant figure out where.
@Dariusz
issetSelectionOnDroppedItems()
still called from within dropEvent handler?I am personally not a big fan of
QCoreApplication::processEvents();
since it can break up so much stuff inside Qt. And i never encountered a case where it was absolutely necessary.You can try to restore the selection after you let Qt getting finished with the drop event.
QMetaObject::invokeMethod(this, &setSelectionOnDroppedItems, Qt::QueuedConnection ); // will be executed in the next event loop iteration
-
@raven-worx
"is setSelectionOnDroppedItems() still called from within dropEvent handler?"Its the last function being called so :
void myTree::dropEvent(QDropEvent *event) { if (event->mimeData()->hasFormat(myFormat)) { processLocalDropEvent(event); } dropIndicatorRect = QRect(); dragActive = false; } void myTree:: processLocalDropEvent(QDropEvent *event){ //// There is a lot more here, like deciding on what to drop and so on, but basic version is as follow _droppedNodes = model()->dropMyMimeItems(event->mime,row,index,etc) stopAutoScroll(); setState(NoState); viewport()->update(); // can remove it from here/ use later in selection function. setSelectionOnDroppedItems(_droppedNodes ); } void myTree::setSelectionOnDroppedItems(std::vector<myNodes*> _droppedNodes) { clearSelection(); int dataSize = _droppedNodes.size(); for (int x = 0; x < dataSize; ++x) { QModelIndex itemIndex = _droppedNodes[x]->index(); selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select | QItemSelectionModel::Rows); } }
This is full routine as far as I can tell from dropEvent till end. Will try the QMetaObject::invokeMethod sounds promising! never used it before :O thanks!
Edit. IT WORKS! Amazing ! But Omg I feel so dirty using that method lol...
-
Hey @SGaist just got back to the issue again. So the re-selection is working using that
QMetaObject::invokeMethod(this, "setSelectionOnDroppedItems", Qt::QueuedConnection);
But I noticed that it created another "issue" mainly when I then try to select some items after drop, QT uses old selected item for starting "selection" and selects all until the item I clicked on... I'm bit lost now with it. As I made sure(I probably failed here) I have emitted drop events/mouseRelease events and so on to keep as much as I can of native QT signals but I'm missing something. Any idea what could be wrong here?
Attached video : http://www.dariuszmakowski.com/2018_05_15_09_52_33.mp4
Thanks for help & your time :- )
-
Hey @SGaist just got back to the issue again. So the re-selection is working using that
QMetaObject::invokeMethod(this, "setSelectionOnDroppedItems", Qt::QueuedConnection);
But I noticed that it created another "issue" mainly when I then try to select some items after drop, QT uses old selected item for starting "selection" and selects all until the item I clicked on... I'm bit lost now with it. As I made sure(I probably failed here) I have emitted drop events/mouseRelease events and so on to keep as much as I can of native QT signals but I'm missing something. Any idea what could be wrong here?
Attached video : http://www.dariuszmakowski.com/2018_05_15_09_52_33.mp4
Thanks for help & your time :- )
@Dariusz
it seems like you are not accepting all events?!
So some of them get passed to the parent widget and this confuses the widget implementation. -
@Dariusz
it seems like you are not accepting all events?!
So some of them get passed to the parent widget and this confuses the widget implementation.@raven-worx Hmm So I need to adjust:
dragEnterEvent, dragMoveEvent, dragLeaveEvent, dropEvent ? Give them either
event->acceptProposedAction() or event->ignore() ?
-
@raven-worx Hmm So I need to adjust:
dragEnterEvent, dragMoveEvent, dragLeaveEvent, dropEvent ? Give them either
event->acceptProposedAction() or event->ignore() ?
@Dariusz
if you react to those events , accept them. If not just pass them to the base class implementation.