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;
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.