Events blocked during Drag, but I need to track cursor position.
-
I'm trying to implement a drag and drop operation where you use drag and drop to connect a wire between two widgets. So you start by clicking on the first widget and dragging. Then the wire appears as you drag---one end of the wire is fastened to the first widget at the original click point and the other end of the wire tracks with the mouse cursor. So you're stretching the wire as you move the cursor. Then when you drop the other end of the wire on the second widget it becomes fastened there.
The wire needs to be redrawn as the mouse cursor moves, even when the cursor isn't over a target widget. But I don't see a way to do that since events are blocked during a drag-drop operation. (BTW, I was able to do this fine on another popular GUI framework that doesn't block.)
So what I'm asking is if there is some other, not so difficult way to do this using Qt facilities or idioms. Otherwise, I think I'm going to have to create my own drag-drop solution. But I wanted to ask before I have to do all that.
Thanks,
Jim
-
@minorguy You mentioned that 'events are blocked' - what do you mean by that? That is definitely not true, see for instance http://doc.qt.io/qt-5/qwidget.html#mouseMoveEvent
Depending on how you draw your 'wire', you may need to realize however that the move event is sent to the wire-object instead of the first widget.
-
@Jakob Thanks for the reply. I’m pretty new to Qt. Unfortunately your suggestion hasn't helped me yet. When the drag operation starts I can create a “wire” widget and set mouse tracking to be on for the wire widget, but it doesn’t receive mouse move events during the drag. (I override its mouseMoveEvent()).
I should also mention that everything is in a QGraphicsScene. I wanted everything to be scalable and scrollable in a view and it seemed the best way to so that was to use QGraphicScene and QGraphicView. Since I want some of the things in the view to be widgets, like sliders and comboboxs, I use QGraphicScene::addWidget() so that they get wrapped in a QGraphicsProxyWidget. I don’t know if all this affects how events work. It seems there might be multiple ways to accomplish what I want; I’m not sure the best way yet.
So I’m just looking for anywhere that the mouse cursor position might emerge during a drag operation. So far it seems that the Qt drag-drop mechanism swallows up cursor move events.
(My last resort plan is to abandon drag-drop and try to use QGraphicsScene::itemAt() and/or QApplication::widgetAt(). But I'm not there yet.)Jim
-
@minorguy I'm not very familiar with
QGraphicsScene
unfortunately (yet). I do know absolutely certain though that Qt will most definitely not swallow the mouse events. The trick for you I guess is to figure out where these events are sent.Maybe they are passed to the
QGraphicsScene
object?In order to speed up your search you may want to create a single object that you install as event filter for every object that you have. All events will come through this single object then. There will be loads and loads of them, but with some painstaking (print) debugging you may be able to figure out where the mysterious mouse move events are sent to.
More on event filters here: http://doc.qt.io/qt-5/eventsandfilters.html#event-filters
-
@Jakob Yes, thanks, I may try some of that. Similar to your event filter idea, I had already thought of making every object a drop target and then relay cursor position from each object’s dragMoveEvent() . But as a permanent solution that’s such an ugly hack. I tried overriding mouseMoveEvent() for the QGraphicsScene to see if it is getting mouse events during a drag, but when I do, the widget in the scene no longer gets drag events. So a drag can’t even start.
-
As it turns out, QGraphicsScene::dragMoveEvent() works. I derived a class from QGraphicsScene and override dragMoveEvent() which does receive mouse events during a drag. Then inside dragMoveEvent() I call the base class QGraphicsScene::dragMoveEvent() so that these events get propagated down to the graphics items.
So I think I’m past this problem. Thanks!