当 QGraphicsItem 离开场景窗口时如何从 QGraphicsScene 中删除它
Posted
技术标签:
【中文标题】当 QGraphicsItem 离开场景窗口时如何从 QGraphicsScene 中删除它【英文标题】:How to remove QGraphicsItem from QGraphicsScene when it goes out of scene window 【发布时间】:2015-08-30 14:57:45 【问题描述】:所以我有一个名为 bullet 的项目,我希望它在离开 QGraphicsScene 窗口时清除
我的代码是:
if(bullet->scene() != NULL)
if(bullet->x() >= 800 || bullet->y() >= 600)
scene->removeItem(bullet);
scene->update();
view->update();
qDebug("Bullet went out of screen so it has been removed");
这可行,但我遇到的问题是,完成后它不会让我创建另一个项目符号。
非常感谢您的帮助
【问题讨论】:
【参考方案1】:我假设你的子弹是动画的(因为你知道子弹通常会飞)所以它必须实现一个advance()
方法。
你可以把边界检查放在那里:
// in Bullet::advance() after you advance the bullet position
// if the scene rect doesn't contain the item rect remove from scene
if (!scene()->sceneRect()->contains(boundingRect())) scene()->removeItem(this);
您当前的解决方案假定子弹只会增加其在 X 和 Y 中的位置,并且场景将始终为 800x600,这是糟糕的设计。你可能会扩大窗口,这会立即打破你的逻辑。您可以从右向左射击,这意味着如果您的子弹从左侧离开,它将永远不会从场景中移除。无论场景有多大以及子弹的方向如何,上述解决方案都将有效。
我遇到的问题是完成后它不会让我 创建另一个项目符号项
从您发布的代码来看,您的问题的原因并不清楚。您应该能够根据需要向场景添加尽可能多的项目,或者您的系统可以处理。听起来好像您正在通过指向它的指针手动管理子弹,如果您的场景中只有一个子弹,这似乎是个好主意,但在实际场景中,场景将是完全动态的,您可能有数百个子弹,所以你不能用这种方式跟踪它们。
这就是为什么您必须使您的项目“智能”并在其中实现其管理逻辑的原因,因此您只需跟踪主要项目,例如您的播放器项目。其他一切都应该通过场景和项目之间的交互进行交互。例如,当你的播放器项目发射子弹时,你不应该手动创建它,它应该在你的播放器项目中实现。所以当你打电话给player->shoot()
时,它会scene()->addItem(new Bullet(bulletSpeed, bulletDirection)
或类似的东西。在同样的逻辑流程中,如果子弹离开场景或击中敌人,则会自动移除子弹,并对敌人造成伤害,如果致命,也会将敌人从场景中移除。
请记住,从场景中移除项目时,项目不会被删除,所有权责任转移给您。如果你想从内存中删除它,在你把它从场景中删除后,你可以调用delete this;
,如果它是对该项目的最后一次操作并且将不再被访问的话应该可以。
【讨论】:
虽然这个答案中的所有点都是有效的,但我认为失败的直接原因很可能是最后一点 - 在将项目从场景中移除后不删除它。 我目前没有进歌 我是 QT 新手,想知道您是否可以帮我创建子弹的高级方法? @Fosterdn007 - 我已经帮助了你,我告诉你你做错了什么以及你需要做的一切来纠正它。但是你必须自己做,否则你永远学不会。不要超越自己。您不会从您不够先进而无法理解的解决方案中受益。以上是关于当 QGraphicsItem 离开场景窗口时如何从 QGraphicsScene 中删除它的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失鼠标抓取的情况下将 QGraphicsItem 移动到另一个场景?
PySide/PyQT5:如何从 QGraphicsItem 发出信号?
当我们改变场景时,后台的 MPMoviePlayerController 不会离开页面