How to select multiple items without pressing Ctrl key within QGraphicsScene?

moligaloo picture moligaloo · Sep 28, 2010 · Viewed 8k times · Source

In Qt's QGraphicsScene, if I wanna one item, just click it, and click another selectable item will make the selected item to be unselected. If I want to select multiple items, I'd use Ctrl-key. But this maybe not convenient for some cases, then how to select multiple items without pressing Ctrl-key within QGraphicsScene?

Answer

Jérôme picture Jérôme · Oct 1, 2010

You want to change the default behavior of QGraphicsScene, so you have to create your own scene class, inheriting QGraphicsScene.

In your class, you'll have to reimplement at least mousePressEvent and handle the item selection yourself.

Here is how you could do it (the inherited scene class is called 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());
}

Implementing this way, clicking on an item with select it if it is not already, or will unselect it otherwise.

But be careful, implement mousePressEvent is certainly not enough : you'll have to handle the mouseDoubleClickEventas well if you don't want the default behavior.

Your scene will have to be displayed by a QGraphicsView. Here is an example of a view creating it's own scene (MainFrm class is inheriting 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);
}