qt rubberband selection with specific keyboard key

1.1k Views Asked by At

I have a QGraphicsView and a QGraphicsScene and I enabled

this->setDragMode(QGraphicsView::RubberBandDrag);

for a Rubberband selection. However, in my application it would make sense that you need to press the CTRL key and then move the mouse to start the rubberband selection. Can I accomplish this without making my own QRubberBand? If not, how can I reimplement it?

2

There are 2 best solutions below

4
On

If you have say a QMainWindow that contains your QGraphicsView and Scene, one way to do this would be to overload the keyPressEvent and keyReleaseEvent methods of QMainWindow like this:

void MyMainWindow::keyPressEvent( QKeyEvent * event )
{
  if( event->key() == Qt::Key_Control ) {
    graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
  }
  QMainWindow::keyPressEvent(event);

}


void MyMainWindow::keyReleaseEvent( QKeyEvent * event )
{
  if( event->key() == Qt::Key_Control ) {
    graphicsView->setDragMode(QGraphicsView::NoDrag);
  }
 QMainWindow::keyReleaseEvent(event);

}

This will set the selection mode to RubberBandDrag as long as CTRL is being pressed. When the key is released again, the drag mode is set back to the default NoDrag and no selection is performed. In both cases the event is also forwarded to the QMainWindow base class implementation which may or may not be of relevance for you.

0
On

Erik's answer didn't work well for me. If I release the key while still dragging, the rubber band is not cleared and remains visible on the screen until the next selection.

Because QT only clears the rubber band on mouse release, my workaround was to force an artificial mouse release event while still in Rubberband mode to have it properly cleared:

void MyQGraphisView::keyReleaseEvent( QKeyEvent * event )
{
    if( event->key() == Qt::Key_Control ) {
        if(QApplication::mouseButtons() & Qt::LeftButton)
            mouseReleaseEvent(new QMouseEvent(QApplicationStateChangeEvent::MouseButtonRelease, mousePosOnScene, Qt::LeftButton, Qt::NoButton, Qt::NoModifier));   
        setDragMode(QGraphicsView::NoDrag);
    }
    QMainWindow::keyReleaseEvent(event);

}

Update: Qt fixed this bug (https://bugreports.qt.io/browse/QTBUG-65186) and will be deployed in 5.15