拖动结束时没有调用QTableView mouseRelease事件,bug?

时间:2012-01-31 16:39:52

标签: qt mouseevent qtableview

当用户从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);
}

那么,这是一个错误? 如果你知道一个技巧,它会对我有所帮助。

谢谢!

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

4 个答案:

答案 0 :(得分:1)

问这个问题已经三年了,Qt问题仍然存在于Qt 5.4中。最近我遇到了同样的问题:在应用程序外部删除而没有MouseReleaseEvent。解决方案很简单,并不是一个绝招:

启动拖放的mousePressEvent看起来像这样(简化):

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-&gt; exec()启动它自己的事件循环,当释放鼠标按钮时退出。 drag-&gt; exec(); 之后的鼠标位置可以使用QCursor确定。

答案 1 :(得分:1)

如上所述已经过了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();
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

我遇到了类似的问题,并且不高兴发现MouseReleaseEvent在拖动结束时没有被触发。

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

这至少是我的伎俩。希望它有所帮助。