Qt:将拖放委托给子项的最佳方法

4

我正在使用QWidget的拖放功能,我已经重载了dragEnterEvent、dragLeaveEvent、dragMoveEvent和dropEvent函数,而且一切都很顺利。

在我的QWidget中,我有其他的QWidget子控件,并且我希望它们也能够管理拖放事件。问题是,我的父QWidget捕捉了dnd事件,所以我的子QWidget无法获得它。有什么最好的方法来实现“当鼠标在子控件上方时,子控件获取dnd事件”?

谢谢

编辑:

我的控件长这样:

----------------------------------------
|            Parent Widget             |
|       ------------------             |
|       |  Child Widget  |             |
|       |                |             |
|       ------------------             |
|                                      |
----------------------------------------

我的父部件和子部件属于同一个类。

代码非常基本,类似于这样:

DnDWidget::DnDWidget(QWidget* parent)
    : QWidget(parent)
{
    setAcceptDrops(true);
}

void DnDWidget::dragEnterEvent (QDragEnterEvent* event )
{
    qDebug() << "dragEnterEvent";
    if (event->mimeData()->hasFormat("foo/bar"))
        event->acceptProposedAction();
}

void DnDWidget::dragMoveEvent (QDragMoveEvent* event )
{
    qDebug() << "dragMoveEvent";
    //do visual feedback stuff
}

我的子组件的dragEnterEvent从未被调用。

1个回答

3
拖放文档中得知:
要使小部件能够接收媒体,需要为小部件调用setAcceptDrops(true)函数,并重新实现dragEnterEvent()dropEvent()事件处理程序函数。
以下是简要摘要:
1.子级应该调用setAcceptDrops(true)
2.子级应该重新实现dragEnterEvent并接受其建议的操作。
3.子级应该重新实现dropEvent并接受其建议的操作
如果以上任何一项不正确,则父级将有机会处理下降。

我的子控件确实调用了这些方法。问题在于父控件捕获了该事件,因此我的子控件的dragEnterEvent从未被调用。目前,我认为解决方法是通过QApplication :: sendEvent自己重新发送事件,但我想知道是否有更好的方法。 - robix
孩子将首先看到事件。确保您的函数签名完全匹配,并且重新实现的方法按预期由基类调用。 - Kaleb Pederson
是的,情况就是这样:我的子类和父类实际上是相同的。我可以看到我的父类的DnD视觉反馈,并且我的父类的dragEnterEvent和dragMoveEvent被调用,但是当我移到一个子QWidget上方时,我的父类的dragLeaveEvent没有被调用,也没有调用子类的dragEnterEvent。 - robix
好的,我已经找到问题所在了:我的子部件实际上是在一个QScrollArea中。我能看到QScrollArea,但我的部件是空的,我没有意识到它没有大小(因此我从未在其上拖动)。如果我设置一个setMinimumSize,一切都可以正常工作。现在我感觉很愚蠢 :)。谢谢你的回答。 - robix
笑。感谢诚实回复 :)。 - Kaleb Pederson
@KalebPederson 你有没有想法如何在_child_是QGraphicsScene的情况下重现这个问题?我无法在它上面调用setAcceptDrops()... 我也没有为它使用单独的类,只是在父类的构造函数中像这样调用它:scene = new QGraphicsScene(0, 0, 600, 500); - Joum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接