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

Checking if a drag and drop operation is active?



  • Hi all,

    I am noticing some undesirable behavior (from our point of view), that while a QDrag object is executing, keyboard shortcut can still get processed. This mean the owner of the QDrag could potentially get deleted while the drag is active. In Qt 5.7, I see they have introduced a static cancel function on QDrag but from the description it doesn't seem to work on macOS yet.

    We would like a consistent behavior and I was wondering if there is a way to tell if a QDrag is executing at the moment?

    I can see there is a QDragManager which is not public and trying to use it seems complicated (it includes "private/qobject_p.h"). Also tried the findChild() approach, but might have to consider iterating through QGraphicsScene on my own, the recursion in findChild() doesn't seem to do that.


  • Lifetime Qt Champion

    Hi,

    What would you like to do with that information ?
    One possible way would be to emit a signal from the object at the origin of the drag before starting the drag and one after it's done.



  • Hi SGaist,

    I have an application wide event filter and I was hoping if a QDrag object is active (i.e. we are in the process of drag and drop), we ignore all shortcut except escape key.


  • Moderators

    @Thuan_Firelight
    why do you handle shortcuts with an application wide eventfilter?
    Such a design is rather the source of your unexpected misbehavior.



  • @raven-worx said in Checking if a drag and drop operation is active?:

    @Thuan_Firelight
    why do you handle shortcuts with an application wide eventfilter?
    Such a design is rather the source of your unexpected misbehavior.

    Currently we don't, but I imagine handling at every widget level is going to be a nightmare if the behavior intented was that when dragging and dropping user shouldn't be allowed to perform keyboard shortcut such as undo or redo. Do welcome any other suggestion that would allow for the same behavior that is not via a eventfilter. I can probably also do it in the bit where we push or pop from the undo stack, but that still requires knowledge that we are in a drag and drop operation.


  • Lifetime Qt Champion

    This post is deleted!

  • Moderators

    @Thuan_Firelight said in Checking if a drag and drop operation is active?:

    Currently we don't, but I imagine handling at every widget level is going to be a nightmare if the behavior intented was that when dragging and dropping user shouldn't be allowed to perform keyboard shortcut such as undo or redo

    Qt is a rich UI framework, thus it of course provides also a shortcut concept (using QShortcut)
    When using QShortcut it is all about setting the context properly. I am not aware of a system which triggers shortcuts during DnD operations anyway. QShortcut takes the current focus scope (and the set context) into account for determining which shortcut to trigger.



  • @raven-worx said in Checking if a drag and drop operation is active?:

    @Thuan_Firelight said in Checking if a drag and drop operation is active?:

    Currently we don't, but I imagine handling at every widget level is going to be a nightmare if the behavior intented was that when dragging and dropping user shouldn't be allowed to perform keyboard shortcut such as undo or redo

    Qt is a rich UI framework, thus it of course provides also a shortcut concept (using QShortcut)
    When using QShortcut it is all about setting the context properly. I am not aware of a system which triggers shortcuts during DnD operations anyway. QShortcut takes the current focus scope (and the set context) into account for determining which shortcut to trigger.

    Not sure if I understand, do you mean Qt is not support to do that? I have a simplified version below demonstrating what I am seeing :

    int Application::exec()
    {
        QMainWindow* testWindow = new QMainWindow;
        testWindow->resize(500, 500);
        QTreeWidget* tree = new QTreeWidget();
        tree->setAcceptDrops(true);
        tree->setDragEnabled(true);
        tree->setDragDropMode(QAbstractItemView::InternalMove);
        testWindow->setCentralWidget(tree);
    
        QTreeWidgetItem* dad = new QTreeWidgetItem(tree,0);
        dad->setText(0, "Hello");
        QTreeWidgetItem*  child = new QTreeWidgetItem(dad,0);
        child->setText(0, "World");
    
        QMenu* testMenu = testWindow->menuBar()->addMenu("Test");
        QAction* action = testMenu->addAction("Keyboard Shortcut Triggered");
        action->setShortcut(Qt::ControlModifier + Qt::Key_D);
        connect(action, &QAction::triggered, testWindow, [testWindow]() { qDebug() << "Action triggered!!"; });
        testWindow->showNormal();
        
        return QApplication::exec();
    }
    

    As I am dragging the item in the tree widget while holding the left mouse button, I can hit Ctrl+D to trigger the action and I am seeing the "Action triggered" getting printed to the console. It is not exactly clear cut though since the log only appears intermittently (i.e. if I hold down Ctrl and hit D 5 times, I might see the log only 2 times as I drag around inside the window).

    According to the doc, the shortcut context for QAction is Qt::WindowShortcut which sounds about right to me.


  • Moderators

    @Thuan_Firelight said in Checking if a drag and drop operation is active?:

    As I am dragging the item in the tree widget while holding the left mouse button, I can hit Ctrl+D to trigger the action and I am seeing the "Action triggered" getting printed to the console.

    oh really?! i wasn't aware of that. Doesn't make sense to me though, sicne CTRL should be handled by the drag itself.


Log in to reply