如何在QGraphicsScene中不按Ctrl键选择多个项目?

6
在Qt的QGraphicsScene中,如果我想要选中一个项目,只需单击它,然后单击另一个可选择的项目将使所选项目取消选择。 如果我想选择多个项目,则应使用Ctrl键。 但是在某些情况下,这可能不方便,那么如何在QGraphicsScene中在不按Ctrl键的情况下选择多个项目?

您希望以何种方式选择多个项目?是拖动一个矩形框选,还是在时间延迟内单击?请明确您的需求。 - Live
如果我想选择A和B,我必须默认先单击A,然后按住Ctrl键,再单击B。我希望能够以这种方式选择多个项目:只需单击A,然后单击B,A和B都将被选中。 - moligaloo
你需要重新实现void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) [protected],但我无法确定具体的实现方式。 - Live
如果您能提供一个更新,展示您是如何解决这个问题的,那将非常好。这样,如果其他遇到同样问题的用户发现了这个问题,他们就可以从您的经验中受益。 - Simon Hibbs
2个回答

8
您希望更改QGraphicsScene的默认行为,因此您需要创建自己的场景类,继承QGraphicsScene
在您的类中,您必须重新实现至少mousePressEvent并自己处理项目选择。
以下是您可以执行此操作的方法(继承的场景类称为GraphicsSelectionScene):
void GraphicsSelectionScene::mousePressEvent(QGraphicsSceneMouseEvent* pMouseEvent) {
    QGraphicsItem* pItemUnderMouse = itemAt(pMouseEvent->scenePos().x(), pMouseEvent->scenePos().y());

    if (!pItemUnderMouse)
        return;
    if (pItemUnderMouse->isEnabled() &&
        pItemUnderMouse->flags() & QGraphicsItem::ItemIsSelectable)
        pItemUnderMouse->setSelected(!pItemUnderMouse->isSelected());
}

实现这种方式,如果项目尚未选定,则单击该项目将选择它,否则将取消选择。
但要小心,仅实现 mousePressEvent 是不够的:如果您不想使用默认行为,则还必须处理 mouseDoubleClickEvent
您的场景必须由 QGraphicsView 显示。以下是一个视图创建自己的场景的示例(MainFrm 类继承了 QGraphicsView):
#include "mainfrm.h"
#include "ui_mainfrm.h"
#include "graphicsselectionscene.h"
#include <QGraphicsItem>

MainFrm::MainFrm(QWidget *parent) : QGraphicsView(parent), ui(new Ui::MainFrm) {
    ui->setupUi(this);

    // Create a scene with our own selection behavior
    QGraphicsScene* pScene = new GraphicsSelectionScene(this);
    this->setScene(pScene);

    // Create a few items for testing
    QGraphicsItem* pRect1 = pScene->addRect(10,10,50,50, QColor(Qt::red), QBrush(Qt::blue));
    QGraphicsItem* pRect2 = pScene->addRect(100,-10,50,50);
    QGraphicsItem* pRect3 = pScene->addRect(-200,-30,50,50);

    // Make sure the items are selectable
    pRect1->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect2->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect3->setFlag(QGraphicsItem::ItemIsSelectable, true);
}

非常感谢!我复制了你的代码并做了一些小改动,现在可以在我的程序中正常运行。 - moligaloo

2

也许这是一种hack方式,但对我来说很有效。在这个例子中,您可以使用shift键选择多个项目。

void MySceneView::mousePressEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mousePressEvent(event);
}


void MySceneView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mouseReleaseEvent(event);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接