我目前正在开发一个图像查看器应用程序。在这个应用程序中,我有一个所谓的" pan-zoom"特征。这意味着,当按住某个鼠标按钮时,用户可以通过前后平移来缩放图像。
它工作正常,但随着功能的使用,鼠标(自然地)在屏幕上上下移动,并在某些时候到达屏幕边框,这将使其停止。相反,我想要一种鼠标保持静止且只有图像放大率发生变化的行为。
我尝试通过在QCursor::setPos
内调用QWidget::mouseMoveEvent
并在处理完移动后将鼠标重置到初始位置来实现此目的。它的工作原理是鼠标几乎静止不动(它向前和向后摆动)。但是,这将导致再次调用鼠标移动事件,从而有效地取消我刚刚进行的调整。这将导致“摆动”"影响。每次调整都会立即逆转。
这是一段剪辑的代码,因此您可以了解我在做什么:
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
?
答案 0 :(得分:1)
我会有一个标志来禁用该事件,默认情况下为false。
在事件内部检查flag是否为false,然后执行zoom操作,将flag设置为true并重置光标。
然后将再次调用该事件并且该标志将为true,因此您将flag设置为false并且您将准备好处理下一个事件。
您必须确保在从setCursor调用接收事件之前,没有对实际鼠标触发鼠标事件进行两次或更多次调用。
答案 1 :(得分:1)
假设您没有调用基类mouseMoveEvent
,则应accept the event将其标记为已处理。默认情况下,当您重新实施该事件时,它们会被接受,但更明确的是它更明确。致电e->accept( )
。
如果您处理任何鼠标事件you should handle all,也建议您使用鼠标双击可能除外。
以下是保持鼠标静止的示例,但在OS X上偶尔出现闪烁,这似乎是由于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
来电,当光标在小部件外部时按下鼠标按钮,这仍然会收到移动事件。 / p>
但是,缩放时可能会提供更好的用户体验hiding the cursor。
答案 2 :(得分:0)
在鼠标事件中不要使用event-> pos(),请使用QCursor :: pos()intead并检查它是否已更改。像这样:
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;
}