将 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 ©Item) { // 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) 位置。也许问题出在复制构造函数中,但我不知道哪里出了问题。
希望有人能帮我指点一下
Update: 看来问题出在CollectionView::update()
函数中...在循环末尾添加一个'delete'删除了item从集合中...或在 ShapeView::addItem()
函数中...我是在创建该项目的副本还是只是重复使用它?
但是如何创建该项目的副本?
我的假设是我在 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 已经有一个副本。 (处理我自己的项目列表有一个好处——项目的 bringForward 和 sendBackward 更容易实现,因为我的 z 值等于项目索引)
我正在尝试在一个面板中创建项目并添加到第二个面板。在第二个面板中,我希望它们是可移动的(并且有上下文菜单)。 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 ©Item) { // 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) 位置。也许问题出在复制构造函数中,但我不知道哪里出了问题。
希望有人能帮我指点一下
Update: 看来问题出在CollectionView::update()
函数中...在循环末尾添加一个'delete'删除了item从集合中...或在 ShapeView::addItem()
函数中...我是在创建该项目的副本还是只是重复使用它?
但是如何创建该项目的副本?
我的假设是我在 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 已经有一个副本。 (处理我自己的项目列表有一个好处——项目的 bringForward 和 sendBackward 更容易实现,因为我的 z 值等于项目索引)