在mousePressEvent()中更改QWidget父级不起作用

Changing the QWidget parent while in a mousePressEvent() doesn't work

本文关键字:QWidget 不起作用 mousePressEvent      更新时间:2023-10-16

我正在更改QWidget的父小部件,我单击该小部件的目的是在父小部件区域周围拖动该小部件。我需要在mousePressEvent()回调中更改父级,因为前一个父级的框架非常有限。

这会产生意想不到的结果,即似乎丢失了鼠标事件,并且必须再次单击才能开始响应mouseMoveEvent()

如果发生这种情况,我所拥有的就是以下内容。

cardWidget->setParent(feltWidget);
cardWidget->show();

如果我删除setParent()调用,它会按预期工作。如何使我仍然能够更改父级,但看起来好像我的鼠标光标被破坏并创建了一个新对象。

我遇到了类似的问题,涉及在mouseEvents期间更改QDockWidget的父级。以下是我从调试Qt和我想出的解决方案中学到的,最终我还是没有采取:不要这样做,它会导致其他不需要的Qt行为。

我所做的是在"重新育儿"之前和之后发送 MouseMove 事件,以再次触发"拖动"机制(因为重新育儿停止了它)。这是特定于QDockWidgets的,我不确定这是否适用于您的情况。但是,下面是相关代码:

    // end the drag before re-parenting
    QMouseEvent endDrag(QEvent::NonClientAreaMouseMove, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    const bool handledEndDrag = QApplication::sendEvent(&dockWidget, &endDrag);
    assert(handledEndDrag);
    // set this attribute to avoid a hide()-event spoiling the drag-and-drop
    dockWidget.setAttribute(Qt::WA_WState_Hidden, true);
    // ... do re-parenting
    dockWidget.setAttribute(Qt::WA_WState_Hidden, false);
    // trigger start drag again
    QMouseEvent* startDrag =
        new QMouseEvent(QEvent::NonClientAreaMouseButtonPress, dockWidget.mapFromGlobal(QCursor::pos()),
                        Qt::LeftButton, Qt::LeftButton, QApplication::keyboardModifiers());
    QApplication::postEvent(&dockWidget, startDrag);
    // fake this mouse move event to continue dragging
    QMouseEvent mouseMove(QEvent::MouseMove, current->pos(), current->pos(), Qt::NoButton,
                QApplication::mouseButtons(), QApplication::keyboardModifiers());
    const bool handledMouseMove = QApplication::sendEvent(m_dock, &mouseMove);
    assert(handledMouseMove);

您必须调试一些Qt代码,以便完全了解特定情况下的情况。似乎这还不够:不同的Qt版本也可能表现不同。

如你所知,我做这件事有很多"乐趣"。祝你好运,愿QForce与你同在。