В настоящее время я занимаюсь разработкой приложения для просмотра изображений. В этом приложении у меня есть так называемая функция панорамирования. Это означает, что, удерживая определенную кнопку мыши, пользователь может увеличивать изображение, перемещаясь вперед и назад.
Он работает нормально, но при использовании этой функции мышь (естественно) перемещается вверх и вниз по экрану и в какой-то момент достигнет границ экрана, что приведет к ее остановке. Вместо этого мне бы хотелось поведение, при котором мышь остается неподвижной и изменяется только увеличение изображения.
Я пытался добиться этого, вызывая 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
?
Предполагая, что вы не вызываете базовый класс mouseMoveEvent
, вам следует принять событие пометить его как обработанный. По умолчанию они принимаются, когда вы повторно реализуете событие, но это более ясно, чтобы быть явным. Вызов e->accept( )
,
Также рекомендуется, что если вы обрабатываете любое из событий мыши, ты должен справиться со всеми, с возможным исключением двойного щелчка мышью.
Вот пример того, как держать мышь неподвижно, хотя в 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
вызов, и он все равно будет получать события перемещения, когда курсор находится за пределами виджета, в то время как кнопка мыши удерживается нажатой.
Тем не менее, это может быть лучшее взаимодействие с пользователем скрывая курсор при масштабировании.
У меня был бы флаг, чтобы отключить событие с будет ложным по умолчанию.
внутри события проверьте, если флаг равен false, затем выполните операцию масштабирования, установите флаг в значение true и сбросьте курсор.
тогда событие будет вызвано снова, и флаг будет истинным, поэтому вы установите флаг в ложь, и вы будете готовы обработать следующее событие.
Вам просто нужно убедиться, что у вас нет двух или более вызовов для вызова события мыши с фактической мыши, прежде чем получить событие от вызова setCursor.