拖动结束时未调用QTableView mouseRelease事件,错误



当用户从QTableView拖动项目并释放左按钮时,我只想捕捉mouseRelease事件

我想在我的应用程序中突出显示可能的放置区域,比如更改小部件的背景。我从检测拖动开始,通过重新实现:

void LibraryTableView::startDrag( Qt::DropActions supportedActions )
{
    m_dragReleased = false;
    emit dragStart();
    QTableView::startDrag(supportedActions);
}

并发出我自己的信号。

现在dropzone已经更改,无论拖放是否成功,我都需要捕捉释放事件来像以前一样重新绘制dropzone

我尝试了不同的模型,重新实现了4个鼠标事件和eventFilter,但鼠标释放事件从未被捕获。

这是我的代码:

void LibraryTableView::mouseDoubleClickEvent( QMouseEvent* event )
{
    QTableView::mouseDoubleClickEvent(event);
}
void LibraryTableView::mouseMoveEvent( QMouseEvent* event )
{
    qDebug() << "move";
    QTableView::mouseMoveEvent(event);
}
void LibraryTableView::mousePressEvent( QMouseEvent* event )
{
    qDebug() << "press";
    QTableView::mousePressEvent(event);
}
void LibraryTableView::mouseReleaseEvent( QMouseEvent* event )
{
    qDebug() << "real"; // Never called when drag ends ...
    QTableView::mouseReleaseEvent(event);
}

那么,这是一个bug?如果你知道一个窍门,那对我会有很大帮助。

谢谢!

编辑:我不能为我的应用程序中的每个小部件重新实现dropEvent,如果用户在另一个应用程序中拖放元素,我仍然想捕捉发布事件。。。

如上所述,这已经过去了3年,但多亏了最后一个答案,我找到了一个更简单的解决方案。

void LibraryTableView::startDrag( Qt::DropActions supportedActions )
{
    m_dragReleased = false;
    emit dragStart();
    QTableView::startDrag(supportedActions);
    //CODE HERE WILL BE EXECUTED ONLY WHEN THE MOUSE BUTTON HAS
    //BEEN RELEASED SO YOU CAN DO THE FOLLOWING
    emit dragStop();
}

自提出此问题以来的三年,此Qt问题在Qt 5.4中仍然存在。最近,我遇到了同样的问题:在应用程序之外出现了鼠标释放事件。解决方案很简单,并不是一个真正的技巧:

启动拖动&下降看起来像这样(简化):

void DragNDropListView::mousePressEvent(QMouseEvent *event){
        ....
        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;
        mimeData->setData("application/x-xxxxxx", QByteArray());
        drag->setMimeData(mimeData);
        drag->exec();
            // The d&d ended here. Inside the widget where the drag
            // started, a mouseReleaseEvent would have been fired.
            // Outside this widget not.
            // drag->mimeData() is here still available.
        }
    }
}

诀窍很简单:drag->exec()启动自己的事件循环,当释放鼠标按钮时就会退出。拖动->exec()之后的鼠标位置可用QCursor测定。

对于QTableView,您必须重新实现三个支持dnd的功能:

  • void dragEnterEvent ( QDragEnterEvent * event )-在该功能中,鼠标进入小部件
  • void QAbstractItemView::dragMoveEvent ( QDragMoveEvent * event )-在此功能中,您可以更新您的投放区域高亮显示
  • void QAbstractItemView::dropEvent ( QDropEvent * event )-在此函数中,您可以决定是否接受事件

我遇到了类似的问题,很不高兴发现鼠标释放事件在拖动结束时没有被触发。

我只是使用了DragLeaveEvent并关闭了我的变量,就像我在MouseReleaseEvent中所做的那样。如果用户拖离应用程序,然后重新打开,那么之前关闭的变量将在DragMoveEvent中重新启用(假设它被接受)。

至少那是我的把戏。希望能有所帮助。

最新更新