如何使用Qt在QCursor::setPos()上阻止mouseMoveEvent
How to prevent mouseMoveEvent on QCursor::setPos() using Qt?
我目前正在开发一个图像查看器应用程序。在这个应用程序中,我有一个所谓的"平移-缩放"功能。这意味着,当按住某个鼠标按钮时,用户可以通过前后平移来缩放图像。
它工作得很好,但当使用该功能时,鼠标(自然地)在屏幕上上上下移动,并在某个点到达屏幕边界,这将使它停止。相反,我希望鼠标保持静止,只有图像放大率发生变化。
我试图通过调用QWidget::mouseMoveEvent
内部的QCursor::setPos
并在处理完移动后将鼠标重置到初始位置来实现这一点。它的工作原理是鼠标几乎保持静止(来回摆动)。然而,这将导致再次调用鼠标移动事件,从而有效地取消我刚才所做的调整。这将导致"摆动"效应。每次调整都将立即反转。
这里有一个代码剪辑,所以你可以了解我在做什么:
void ImageView::mouseMoveEvent(QMouseEvent *e) {
//some code
if (_panZooming) {
//some code here
//doesn't work as expected because it invokes this event again
QCursor::setPos(mapToGlobal(_initialMousePosition.toPoint()));
}
}
在使用QCursor::setPos
时,有没有办法防止鼠标移动事件发生?
假设您没有调用基类mouseMoveEvent
,那么您应该接受该事件以将其标记为已处理。默认情况下,当您重新实现事件时,它们会被接受,但更清楚的是要明确。致电e->accept( )
。
还建议,如果您处理任何鼠标事件,则应处理所有事件,鼠标双击可能除外。
下面是一个保持鼠标静止的例子,尽管在OSX上偶尔会有闪烁,这似乎是由于Qt如何处理事件
class MyWidget : public QWidget
{
void mousePressEvent(QMouseEvent* e)
{
m_pos = e->globalPos();
m_lastPos = m_pos;
QWidget::mousePressEvent(e);
}
void mouseMoveEvent(QMouseEvent* e)
{
// Calculate relative zoom factor
// scaled down ( / 10 ) for image zooming
m_zoomFactor += ((float)e->globalPos().y() - m_lastPos.y()) / 10;
QCursor::setPos(m_pos);
m_lastPos = m_pos;
e->accept();
qDebug() << m_zoomFactor << endl;
}
void mouseReleaseEvent(QMouseEvent* e)
{
QWidget::mouseReleaseEvent(e);
}
private:
QPoint m_pos;
QPoint m_lastPos;
float m_zoomFactor = 0; // C++ 11 initialisation
};
如果您不想让鼠标保持静止,请执行QCursor::setPos
调用,当光标位于小部件外部时,按住鼠标按钮时,该调用仍将接收移动事件。
然而,在缩放时隐藏光标可能是更好的用户体验。
我有一个禁用事件的标志,默认情况下为false。
在事件内部检查标志是否为false,然后执行缩放操作,将标志设置为true并重置光标。
然后将再次调用该事件,并且该标志将为true,因此将该标志设置为false,就可以处理下一个事件了。
在从setCursor调用接收事件之前,您只需要确保没有两个或多个从实际鼠标触发的鼠标事件调用。
不要在鼠标事件中使用event->pos(),使用QCursor::pos(。像这样:
void MyWidget::mousePressEvent(QMouseEvent *)
{
mPrevPos=QCursor::pos();
mMoving=false;
}
void MyWidget::mouseMoveEvent(QMouseEvent *)
{
auto cursorPos=QCursor::pos();
if(mPressedPos==cursorPos){
return;
}
if(!mMoving
&& (cursorPos-mPrevPos).manhattanLength()>QApplication::startDragDistance()){
mMoving=true;
}
if(mMoving){
auto diff=cursorPos-mPrevPos;
// move something using diff
QCursor::setPos(mPrevPos);
}
}
void MyWidget::mouseReleaseEvent(QMouseEvent *)
{
mMoving=false;
}
void MyWidget::leaveEvent(QEvent *)
{
mMoving=false;
}
- 如何在 Qt 5 上使用 mouseMoveEvent on paintEvent ?
- Qt mouseMoveEvent-跟踪鼠标位置
- 不抓取时的QGraphicsPixmapItem mouseMoveEvent
- Qt GraphicsView mouseMoveEvent shadowing GraphicsItem mouseM
- 如何使用Qt在QCursor::setPos()上阻止mouseMoveEvent
- Qt mouseMoveEvent不触发当鼠标按下
- 我如何接收或能够在我的小部件窗口外处理mouseMoveEvent(s)
- Qt MouseMoveEvent仅在按下鼠标按钮时触发
- QGraphicsScene mouseMoveEvent不工作,直到qgraphicsviewwheelevent
- 用mouseMoveEvent约束QGraphicsItem移动
- mouseMoveEvent is not called
- 当嵌入一个应用程序到Qt应用程序,如何获得mouseMoveEvent和嵌入窗口的大小
- 在Qt5的QQuickItem 上捕获mouseMoveEvent