0

我有一个对象列表,用于将对象添加到 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);
}

稍后,在 GraphicsScene 类中,我检测用户何时单击一个项目并拖动它以移动它:

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

这适用于在图形视图中移动项目,但我无法将 QGraphicsItem 追溯到创建它的列表项。

将 QGraphicsItem 与创建它的列表项链接的最佳方法是什么,以便可以更改列表项以反映位置的变化?

4

2 回答 2

0

最好的方法是不需要手动同步列表中的项目和场景中的项目。
做到这一点的最佳方法取决于您的设计 - 可能您的项目可以成为指向场景中项目的指针,或者它们可以容纳那些。

于 2011-07-18T01:42:11.817 回答
0

您可以为域对象中的每个项目分配一个QUuid属性,并将其传递给QGraphicsItem. 我已经在一个项目中使用了它,并且效果很好。我在我的域模型中添加了一个QHash查找表以使其更高效,但对于较短的列表来说这不是必需的。

于 2011-07-18T13:57:32.257 回答