将QGraphicsItem从一个QGraphicsScene复制到另一个,项目捕捉到(0,0)(copying QGraphicsItem from one QGraphicsScene to an

编程入门 行业动态 更新时间:2024-10-27 11:16:49
将QGraphicsItem从一个QGraphicsScene复制到另一个,项目捕捉到(0,0)(copying QGraphicsItem from one QGraphicsScene to another, items snap to (0,0))

我正在尝试在一个面板中创建项目并添加到第二个面板。 在第二个面板中,我希望它们可以移动(并具有上下文菜单)。 AddItem按钮应该将RenderArea中的项添加到CollectionView中的现有项目列表(可能已经移动了)

在下面的代码中, ShapeView::addItem()应该从RenderArea创建项目的副本(它可以改变形状,颜色等但不能移动,从(0,0)开始),将它放入CollectionView ,它是可移动的。 RenderArea包含一个项 - 一旦添加到CollectionView , RenderArea项应该重置。

发生了什么......我似乎无法将项目与两个类别分开。

当我添加项目时,即使CollectionView的项目已移动,它们的位置也会重置为0,0 (或者RenderArea的初始位置;但是添加正常,单个项目属性是正确的,如形状和颜色;另外 - CollectionView项目移动,RenderArea项目没有)。

我发布了所有相关代码:

class Item : public QGraphicsItem { Item() { setFlag(ItemIsMovable, false); } Item::Item(Item &copyItem) { // copy constructor setFlag(ItemIsMovable); setPos(copyItem.pos()); // doesn't seem to work QRectF boundingRect() const { return QRectF(-35, -30, 35, 20); } void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) { painter->drawRect(boundingRect()); } protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem::mouseMoveEvent(event); } }; 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); s->setSceneRect(-width()/2, -height()/2, width(), height()); 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(m_items->at(i)->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); s->setSceneRect(-width()/2, -height()/2, width(), height()); setScene(s); setViewportUpdateMode(BoundingRectViewportUpdate); item = new Item(); 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); 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(); }

我复制项目的方式都有问题,我只是不知道是什么。 我没有理由在添加项目时, CollectionView项目都会捕捉到(0,0)位置。 也许问题出在复制构造函数中,但我无法弄清楚是什么问题。

我希望有人可以帮我一个提示

更新 :似乎问题出现在CollectionView::update()函数中...在循环结束时添加'delete'会从集合中删除项目...或者在ShapeView::addItem()函数中...我是创建该项目的副本还是只是重复使用它?

但是如何创建项目的副本?

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, starts at (0,0)), 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.

When I add item, even if the items in CollectionView have moved, their position resets to 0,0 (or whatever the initial position was in the RenderArea; but the adding works properly, the individual item properties are correct, like shape and color; also - CollectionView items move, RenderArea item doesn't).

I am posting all the relevant code:

class Item : public QGraphicsItem { Item() { setFlag(ItemIsMovable, false); } Item::Item(Item &copyItem) { // copy constructor setFlag(ItemIsMovable); setPos(copyItem.pos()); // doesn't seem to work QRectF boundingRect() const { return QRectF(-35, -30, 35, 20); } void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) { painter->drawRect(boundingRect()); } protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem::mouseMoveEvent(event); } }; 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); s->setSceneRect(-width()/2, -height()/2, width(), height()); 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(m_items->at(i)->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); s->setSceneRect(-width()/2, -height()/2, width(), height()); setScene(s); setViewportUpdateMode(BoundingRectViewportUpdate); item = new Item(); 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); 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, I just don't know what. 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

Update: It seems that the problem is in the CollectionView::update() function... adding a 'delete' at the end of the loop removes the item from the collection... Or in the ShapeView::addItem() function... Am I creating copy of the item or just reusing it ?

But how do I create a copy of the item ?

最满意答案

我的假设是我在QGraphicsScene上绘制的项目与它们的表示之间存在联系(作为指向对象的指针)。 错......实际上我误解了指针指向的是什么......

鼠标移动后我更新了列表中项目的位置,一切都很好。

void CollectionView::mouseMoveEvent(QMouseEvent *event) { Item *currentItem = (Item*)itemAt(event->pos().x(), event->pos().y()); if(!currentItem) return; QGraphicsView::mouseMoveEvent(event); m_items->at(currentItem->z)->setPos(currentItem->pos()); }

以上修复了显示的代码。 但这不是最好的解决方案。

更好的解决方案 - 完全删除我的项目列表 ,因为QGraphicsScene已经拥有副本。 (处理我自己的项目列表有一个好处 - 因为我的z值等于项目索引,所以项目的bringForward和sendBackward更容易实现)

My assumption was that there was a connection between the items I paint on QGraphicsScene and their representation (as pointers to the objects). Wrong... In fact I misunderstood what the pointer was pointing at...

I updated the position of the items in my list after mouse move and everything is fine.

void CollectionView::mouseMoveEvent(QMouseEvent *event) { Item *currentItem = (Item*)itemAt(event->pos().x(), event->pos().y()); if(!currentItem) return; QGraphicsView::mouseMoveEvent(event); m_items->at(currentItem->z)->setPos(currentItem->pos()); }

The above fixes the code shown. But it is not the best fix.

The better solution to the problem - remove my list of items completely, since QGraphicsScene already holds a copy. (there was one benefit of handling my own list of items - bringForward and sendBackward for items was easier to implement since my z values were equal to item index)

更多推荐

本文发布于:2023-07-26 03:45:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1270678.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:捉到   项目   QGraphicsScene   QGraphicsItem   items

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!