带有特定键盘键的 Qt 橡皮筋选择

qt rubberband selection with specific keyboard key

本文关键字:Qt 橡皮筋 选择 键盘      更新时间:2023-10-16

我有一个QGraphicsView和一个QGraphicsScene,我启用了

this->setDragMode(QGraphicsView::RubberBandDrag);

用于橡皮筋选择。但是,在我的应用程序中,您需要按 CTRL 键,然后移动鼠标以开始橡皮筋选择是有意义的。我可以在不制作自己的QRubberBand的情况下完成此操作吗?如果没有,我该如何重新实现它?

如果你有一个包含你的QGraphicsView和场景的QMainWindow,一种方法是重载QMainWindow的keyPressEventkeyReleaseEvent方法,如下所示:

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

只要按下 CTRL,就会将选择模式设置为 RubberBandDrag。再次释放键时,拖动模式将设置回默认NoDrag并且不执行任何选择。在这两种情况下,事件也会转发到 QMainWindow 基类实现,这可能与您相关,也可能与您无关。

埃里克的回答对我来说效果不佳。如果我在仍然拖动的同时释放键,橡皮筋不会清除,并且在屏幕上保持可见,直到下一个选择。

由于 QT 仅在鼠标释放时清除橡皮筋,我的解决方法是在仍处于橡皮筋模式时强制人工鼠标释放事件以正确清除它:

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

更新:Qt修复了这个错误(https://bugreports.qt.io/browse/QTBUG-65186),并将在5.15中部署