lundi 20 avril 2015

copying and moving QGraphicsItem from one QGraphicsScene to another, items snap to (0,0)

I am trying to create items in one panel and add to a second panel. In the second panel I want them to be movable (and have context menu). The AddItem button should add the item from the RenderArea, to the existing list of items in the CollectionView (which may already have been moved)

In the code below, the ShapeView::addItem() is supposed to create a copy of the item from the RenderArea (where it can change shape, color etc but is not movable), place it in the CollectionView, where it is movable. The RenderArea holds one item - once added to CollectionView, the RenderArea item should reset.

What is happening... I can't seem to be able to separate the item from the two classes. The item is movable at start, in RenderArea, even though I set the flag to false; when I add item, even if the items in CollectionView have moved, their position resets to 0,0 (but the moving works properly - CollectionView items move, RenderArea item doesn't).

I am posting all the relevant code:

class Item : public QGraphicsItem
{
    Item() { setFlag(ItemIsMovable, false); }   // still item is movable
    Item::Item(Item &copyItem) { setFlag(ItemIsMovable); }
    QRectF boundingRect() const { return QRectF(-35, -30, 35, 20); }
    void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) { painter->drawRect(boundingRect()); }

    QPointF p;  // temporary to fix position
protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
        QGraphicsItem::mouseMoveEvent(event);
        p = this->pos();   // temporary for troubleshooting position
    }
};

class CollectionView : public QGraphicsView
{
    Q_OBJECT    
public:
    CollectionView(QWidget *parent = 0);    
    void update();
    QList<Item*> *m_items;
};

CollectionView::CollectionView(QWidget *parent)
    : QGraphicsView(parent)
{
    QGraphicsScene *s = new QGraphicsScene(this);
    setScene(s);
    setViewportUpdateMode(BoundingRectViewportUpdate);
    m_items = new QList<Item*>();
    scene()->clear();
}

void CollectionView::update()
{
    scene()->clear();
    for(int i = 0; i< m_items->size(); i++)
    {
        Item* item = new Item(*m_items->at(i));
        item->setPos(item->p);  // doesn't seem to work
        scene()->addItem(item);
    }
    viewport()->update();
}

class RenderArea : public QGraphicsView
{
    Q_OBJECT
public:
    RenderArea(QWidget *parent = 0);    
public:
    Item* item;
};

RenderArea::RenderArea(QWidget *parent)
    : QGraphicsView(parent)
{
    QGraphicsScene *s = new QGraphicsScene(this);
    setScene(s);
    setViewportUpdateMode(BoundingRectViewportUpdate);
    item = new Item();
    item->setFlag(QGraphicsItem::ItemIsMovable, false); // not doing anything !!!!!
    s->addItem(item);
}

// this is the boss/coordinator class
class ShapeView : public QGraphicsView
{
    Q_OBJECT
public:
    ShapeView(QWidget *parent = 0);
    CollectionView *collectionView;
private slots:    // more slots corresponding to more controls
    void addItem();
private:    
    QPushButton *addButton;
    RenderArea *renderArea;
};

ShapeView::ShapeView(QWidget *parent)
    : QGraphicsView(parent)
{
    collectionView = new CollectionView(parent);
    renderArea = new RenderArea(this);
    addButton = new QPushButton(tr("Add Item"));
    connect(addButton, SIGNAL(clicked()),
            this, SLOT(addItem()));
}

void ShapeView::addItem()
{   
    Item* item = new Item(*renderArea->item);
  //  item->setFlag(QGraphicsItem::ItemIsMovable);
    collectionView->m_items->append(item);
    collectionView->update();

    // place a new item on renderarea
    renderArea->item = new Item();
    renderArea->scene()->clear();
    renderArea->scene()->addItem(renderArea->item);
    renderArea->viewport()->update();
}

Something is wrong in either the way I copy the item, or using the "ItemIsMovable" flag, or... I just don't know. I see no reason why, when adding items, the CollectionView items all snap to the (0,0) position. Perhaps the issue is in the copy constructor but I can't figure what is wrong.

I hope someone can help give me a hint

Aucun commentaire:

Enregistrer un commentaire