3

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?

Captain GouLash
  • 1,257
  • 3
  • 20
  • 33

2 Answers2

3

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.

Erik
  • 2,137
  • 3
  • 25
  • 42
  • @Amazonasmann I was wondering if this answer solved your problem or if there is something missing from it? Or maybe the question in any case is no longer of relevance to you? – Erik Jul 28 '14 at 06:07
  • I'm having an issue with this approach, if I switch Drag mode while dragging, the rubber band gets frozen in the screen, even after releasing the mouse button. – Adriel Jr Mar 11 '19 at 12:57
  • @AdrielJr not sure I understand the question. What do you mean with switching the mode while dragging? Releasing the control key in the middle of the movement? Sth else? – Erik Mar 14 '19 at 14:34
  • You start dragging with the mouse so that you see the white selection rectangle on the screen, than, without releasing the mouse button, you call setDragMode(QGraphicsView::NoDrag). That is it, you have a frozen white rectangle on your screen until you set the drag mode back to rubber band and start dragging again. There are a few issues in QT Bug track service about this bug: https://bugreports.qt.io/browse/QTBUG-51105 https://bugreports.qt.io/browse/QTBUG-65186 https://bugreports.qt.io/browse/QTBUG-2132 – Adriel Jr Mar 14 '19 at 18:24
1

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

Adriel Jr
  • 2,451
  • 19
  • 25