在 QGraphicsView / QGraphicsScene 上用鼠标移动项目

Moving an item with the mouse on QGraphicsView / QGraphicsScene

我有一个 QGraphicsView 区域显示一些 Item 项。我想实现鼠标移动。

class Item
{
public:
    Item();
    void update();
    int x, y; // position
    int z; // order - should correspond also to index in item list
};

class Collection : public QGraphicsView
{
Q_OBJECT
public:
    Collection(QWidget *parent = 0);
    void update();
    QList<Item> *m_items;
protected:
    virtual void paintEvent(QPaintEvent * event);
    virtual void mousePressEvent(QMouseEvent * event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
private:
    QPoint offset;
    int itemMoved;
};

正在尝试:

void Collection::mousePressEvent(QMouseEvent* event)
{
    Item *currentItem = NULL;
    itemMoved = -1;
    foreach (QGraphicsItem *item, this->items(event->pos()))
    {

// never get into this loop since my items are not children of QGraphicsItem

        currentItem = dynamic_cast<Item*>(item);
        if (event->button() == Qt::LeftButton && currentItem)
        {
            itemMoved = currentItem->z;
            offset = event->pos();
        }
        else if (event->button() == Qt::RightButton)
        {
            // set right click stuff
        }
        else
        {
            event->ignore();
        }
        break;
    }
}

void CollectionView::mouseReleaseEvent(QMouseEvent* event)
{
    if(event->button() == Qt::LeftButton && itemMoved > 0)
    {
        m_items->at(itemMoved).x = event->pos().x();
        m_items->at(itemMoved).y = event->pos().y();

// So far multiple fails:

//    error: assignment of data-member 'Item::x' in read-only structure
//    error: assignment of data-member 'Item::y' in read-only structure
//    error: passing 'const Item' as 'this' argument of 'void Item::update()' discards qualifiers

        m_items->at(itemMoved).update();
        update();
    }
}

我会让我的 Item 继承 QGraphicsItem 但后来我收到关于我不知道如何定义的虚函数的错误(比如 boundingRect 这取决于项目内容...可以是对象、图像、svg、文本...对于某些人我知道如何获取边界矩形但对于其他人来说真的很奇怪)...这是唯一的方法吗?

我如何识别鼠标位置处的项目,是什么阻止我在移动鼠标后更改项目的 xy

如果您要自己实现所有内容,则根本不应该使用 QGraphicsView。如果您希望使用 QGraphicsView,则无需重新实现其任何虚拟方法。只需按原样使用它,并设置项目的 QGraphicsItem::ItemIsMovable 标志。

this answer 中提供了一个完整的示例。重新实现 QGraphicsView::mousePressEvent 的唯一原因是实现新项目的创建。