Prevent QDragEnterEvent from being propagated to parent?
-
Hi,
I would like to prevent a QDragEnterEvent from being propagated to parent. In my widget I override QWidget::dragEnterEvent(QDragEnterEvent *event) to inspect the data and call event->accept() if the data can be dropped on the widget. How can I prevent the event from being propagated to the parent if I don't call event->accept()?
Things I have tried without success
- Override QObject::event(QEvent * e). I case of the event being a QEvent::DragEnter I first call dragEnterEvent and then return true. For other events I call QWidget:event(). QDragEnterEvent still gets propagated to parent widget.
- Install an event filter. I case of the event being a QEvent::DragEnter I first call dragEnterEvent and then return true. For other events return false. QDragEnterEvent still gets propagated to parent widget.
Any ideas?
-
Hi,
What is the issue about letting the event propagate if you do not handle it in that widget ?
-
Hi,
What is the issue about letting the event propagate if you do not handle it in that widget ?
@SGaist It's an MDI application. The user can create new MDI child windows by drag and drop items on empty space in the MDI parent. These MDI child windows are of different type handling different items. So with propagation what's happening is that the user drags an item of type X on a MDI child which only supports items of type Y. The MDI child window rejects the drag but since the event is propagated to the parent which approves it and to the user it looks like the MDI child accepts the drop. When the user does the drop the MDI parent instead creates a new child. Not what the user expects.
-
Can you share your current implementation of the drag and drop ?
-
More background info: the MDI child have a plot area and a tableview area. Drops on the plot area are forwarded to the model of the table view which implements the actual actions to tka.e
void YtScopeSection::dragEnterEvent(QDragEnterEvent *event) { // The table view model will accept drops on itself but we cannot accept drops from the table view to our own plot // area. Hence check that first. if (event->mimeData()->hasFormat("application/x-NewlineSeparatedListOfMeasurementsAndCalibrations") && event->mimeData()->hasFormat("source")) { QByteArray source = event->mimeData()->data("source"); QByteArray us(QString::number((quintptr)&model).toUtf8()); if (source == us) { // Cannot drop from our own table model to plot area => do not accept event. event->ignore(); } else { // Drag source isn't our own table view => delegate to model. if (model.canDropMimeData(event->mimeData(), Qt::MoveAction, 0, 0, model.createIndexName(0))) { event->acceptProposedAction(); } else { // Do not accept event => empty on purpose. event->ignore(); } } } else { // Drag source isn't our own table view => delegate to model. // The last four arguments are not used. if (model.canDropMimeData(event->mimeData(), Qt::MoveAction, 0, 0, model.createIndexName(0))) { event->acceptProposedAction(); } else { // Do not accept event => empty on purpose. event->ignore(); } } } void YtScopeSection::dropEvent(QDropEvent *event) { // The last four arguments are not used. if (model.dropMimeData(event->mimeData(), Qt::MoveAction, 0, 0, model.createIndexName(model.rowCount()))) { event->acceptProposedAction(); } }
-
To avoid the issue of accidentally creating new mdi child, you should check whether there's already a widget under the cursor and in this case do nothing.
-
An event that is ignored means that the current widget will not process it, thus it will go up the chain.