Solved Scrolling a Widget by hand...(mouse)
-
I would like to be able to scroll my custom drawn widget (that is the focus of a QScrollArea) by hand (among other things). However, I cannot get the scroll method for QWidget to work properly. Instead of moving the viewable window, it redraws the same view in a different area.
What I have done so far.
I wrote my own event filter in the core app. I also installed the appropriate filter for the scroll area.
ui.scrollArea->viewport()->installEventFilter(this); ... bool GeoRealismLab::eventFilter(QObject* object, QEvent* event) { if (object == ui.scrollArea->viewport()) { switch(event->type()) { case QEvent::Enter: mapWidget->setFocus(); return true; case QEvent::MouseButtonPress: return mapWidget->onMouseDownEvent(static_cast<QMouseEvent*>(event)); case QEvent::MouseButtonRelease: return mapWidget->onMouseUpEvent(static_cast<QMouseEvent*>(event)); case QEvent::MouseMove: return mapWidget->onMouseMoveEvent(static_cast<QMouseEvent*>(event)); case QEvent::KeyPress: return mapWidget->onKeyPressEvent(static_cast<QKeyEvent*>(event)); case QEvent::KeyRelease: return mapWidget->onKeyReleaseEvent(static_cast<QKeyEvent*>(event)); case QEvent::Wheel: return mapWidget->onWheelEvent(static_cast<QWheelEvent*>(event)); } } return false; }
I have also written the following methods to intercept the appropriate events above:
bool LabMapWidget::onMouseDownEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { mMouseDragging = true; mLastMouseDragLocation = event->pos(); setCursor(Qt::CursorShape::OpenHandCursor); return true; } return false; } bool LabMapWidget::onMouseUpEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { mMouseDragging = false; mLastMouseDragLocation = event->pos(); setCursor(Qt::CursorShape::ArrowCursor); return true; } return false; } bool LabMapWidget::onMouseMoveEvent(QMouseEvent* event) { if (mMouseDragging) { QPoint delta = event->pos() - mLastMouseDragLocation; scroll(delta.x(), delta.y(), rect()); return true; } return false; }
I have also tried the above without the rect(). Like I said, this seems to just drag the picture that I see to another part of the window instead of panning like I want.
I have also tried changing the scrollbar->value()'s for both the horizontal and vertical scroll bars by the change in position. This doesn't work the way I want it to either. I want the part of the picture UNDER the hand cursor to be the same part of the picture under the hand cursor after the move is done.
How can I pan the viewable area?
-
Ok. Figured it out. Sometimes I am an idiot. The scroll method seems to be for doing something else but the scrollbar method works if I update the last position each time onMouseMove is called:
bool LabMapWidget::onMouseMoveEvent(QMouseEvent* event) { if (mMouseDragging) { QPoint delta = event->pos() - mLastMouseDragLocation; //scroll(delta.x(), delta.y(), rect()); mContainer->horizontalScrollBar()->setValue(mContainer->horizontalScrollBar()->value() - delta.x()); mContainer->verticalScrollBar()->setValue(mContainer->verticalScrollBar()->value() - delta.y()); mLastMouseDragLocation = event->pos(); return true; } return false; }