Search code examples
c++qtqgraphicsviewqgraphicsitemqgraphicsscene

Own objects into QGraphicsScene


I would like to have a drag-and-drop feature based on images. If I drag and drop an image I would like to know which image I picked out and moved with (a simple std::string will do to uniquely identify the object that that image is representing). My thought is to store my own object (QPixmapItem) in the QGraphicsScene:

#ifndef QPIXMAPITEM_H
#define QPIXMAPITEM_H

#include <QGraphicsPixmapItem>
#include <QPoint>

class QPixmapItem : public QGraphicsPixmapItem
{
public:
    QPixmapItem(std::string path, std::string id, int x, int y);
    std::string getIdentifier (){return this->identifier;}
    QPoint getPosition () const{return this->position;}

private:
    std::string identifier;
    QPoint position;
};

#endif // QPIXMAPITEM_H

This is the method I use to add my objects to the scene:

void MainWindow::addPixmapItemToScene(std::string path, int x, int y)
{
    // generate pixmap item & add it to the scene
    QPixmapItem *item = new QPixmapItem(path, std::string("id123"), x, y);
    ui->roomView->scene()->addItem(item);

    // only update the affected area
    ui->roomView->updateSceneRect(item->pixmap().rect());
}

Here is how I try to 'catch' the object at a QMouseEvent:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    std::cout << "mouse pressed" << std::endl;

    QGraphicsPixmapItem *currentItem = dynamic_cast<QGraphicsPixmapItem *>(childAt(event->pos()));
    if (!currentItem) {
        return;
    }
    std::cout << "item pressed" << std::endl;
}

The objects are being added to the scene but whenever I press them, the final line ("item pressed") never makes it onto the screen..


Solution

  • QGraphicsItem already support moving by way of drag-and-drop within a QGraphicsScene. All you need is set the QGraphicsItem::ItemIsMovable flag.

    If you want to get notified when that happens, override QGraphicsItem::itemChange() in your custom QGraphicsItem.