I have a list of objects that I use to add objects into a QGraphicsScene:
for(int i = 0; i < levelObjects.length(); i++)
{
QRect objRect;
objRect = spriteSheetLocations.value(levelObjects.at(i).value("frame_name"));
//Q_ASSERT_X(objRect != QRect(0,0,0,0), "MainWindow::loadFile()", "Could not find sprite location!");
QImage img = spriteSheet.copy(objRect);
int height = levelObjects.at(i).value("height").toInt();
int width = levelObjects.at(i).value("width").toInt();
int x = levelObjects.at(i).value("x").toInt();
int y = levelObjects.at(i).value("y").toInt();
img = img.scaled(QSize(width, height), Qt::IgnoreAspectRatio);
item = scene->addPixmap(QPixmap::fromImage(img));
int xPos = x - width/2;
int yPos = levelPlist.value("level_height").toInt() - (y + height/2);
item->setPos(xPos, yPos);
}
Later on, in the GraphicsScene class, I detect when the user clicks on an item and drags it to move it:
void LevelGraphicsView::mousePressEvent(QMouseEvent *event)
{
if (QGraphicsItem *item = itemAt(event->pos())) {
qDebug() << "You clicked on item" << item;
draggedItem = item;
int mouseX = draggedItem->pos().x() - mapToScene(event->pos()).x();
int mouseY = draggedItem->pos().y() - mapToScene(event->pos()).y();
mouseOffset = QPointF(mouseX, mouseY);
} else {
qDebug() << "You didn't click on an item.";
draggedItem = NULL;
mouseOffset = QPointF(0,0);
}
}
void LevelGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
if(!draggedItem) // no item selected
return;
QPointF pos = mapToScene(event->pos()) + mouseOffset;
draggedItem->setPos(pos);
}
This works fine for moving the items in the graphics view, but I’m having trouble tracing the QGraphicsItem back to the list item that created it.
What’s the best way to link the QGraphicsItem with the list item from which it was made so that the list item can be changed to reflect the change of position?
You could assign each item in your domain object a
QUuidproperty and pass this along to a property in yourQGraphicsItem. I have used this on a project and it works quite well. I added aQHashlookup table to my domain model to make it more efficient, but this would not be necessary for shorter lists.