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

2

6

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?

Muslim answered 28/9, 2010 at 6:34 Comment(4)
What way would you like to select multiple items? Dragging a rectangle around, clicking inside a time delay? Precise what you want please.Rowenarowland
If I want to select A and B, I have to click A, and then pressing Ctrl key, and then click B by default. I'd like to select multiple items in this way: just click A and then click B, both A and B will be selected.Muslim
You would have to reimplement void QGraphicsScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [protected], but I cannot precise how exactly.Rowenarowland
It would be good if you could provide an update showing how you solved it, so that if other users with this issue find this question they will benefit from your experience.Coxcombry
I
8

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);
}
Inextricable answered 1/10, 2010 at 12:28 Comment(1)
Thank you very much! I copied your code and made some slight changes, that is works in my program.Muslim
M
2

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);
}
Mopboard answered 3/10, 2013 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.