拖动结束时未调用 QTableView mouseRelease 事件,错误?
Posted
技术标签:
【中文标题】拖动结束时未调用 QTableView mouseRelease 事件,错误?【英文标题】:QTableView mouseRelease event not called when drag ends, bug? 【发布时间】:2012-01-31 16:39:51 【问题描述】:我只想在用户从 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,如果用户在另一个应用程序中拖放元素,我仍然想捕获释放事件...
【问题讨论】:
Drop 事件发生在表格视图之外? 然后鼠标释放在那个小部件上被“捕获”。 【参考方案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】:自从提出这个问题三年后,这个 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->exec() 启动它自己的事件循环,释放鼠标按钮时退出。 drag->exec();之后的鼠标位置可以用QCursor来确定。
【讨论】:
【参考方案3】:对于QTableView
,您必须重新实现三个函数以支持 dnd:
void dragEnterEvent ( QDragEnterEvent * event )
- 在这个函数中鼠标进入小部件
void QAbstractItemView::dragMoveEvent ( QDragMoveEvent * event )
- 在此功能中,您可以更新拖放区突出显示
void QAbstractItemView::dropEvent ( QDropEvent * event )
- 在这个函数中你决定是否接受这个事件
【讨论】:
drop发生在不同的widget中,QTableView是dragOnly 在这种情况下,dropEvent
应该在发生丢弃的小部件中重新实现。
如果用户从我的应用程序中删除了一个元素,我仍然想抓住鼠标Release ...无论小部件是否接受drop。【参考方案4】:
我遇到了类似的问题,我很不高兴发现 MouseReleaseEvent 在拖动结束时没有被触发。
我刚刚使用了 DragLeaveEvent 并关闭了我的变量,就像我在 MouseReleaseEvent 中所做的那样。如果用户拖出应用程序,然后重新打开,那些先前关闭的变量将在 DragMoveEvent 中重新启用(假设它被接受)。
至少这是我的伎俩。希望对您有所帮助。
【讨论】:
以上是关于拖动结束时未调用 QTableView mouseRelease 事件,错误?的主要内容,如果未能解决你的问题,请参考以下文章