Question

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?

Was it helpful?

Solution

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

OTHER TIPS

maybe it's a hack but it's works for me. In this example you can select multiple items using shift key

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top