Qt qgraphicscene::clear()清除场景但不清除视图
我使用从Qt qgraphicscene::clear()清除场景但不清除视图,qt,debugging,qgraphicsview,qgraphicsitem,qgraphicsscene,Qt,Debugging,Qgraphicsview,Qgraphicsitem,Qgraphicsscene,我使用从QGraphicsItem派生的自定义类(Configuration),并将其对象添加到qgraphicscene,然后将其显示在QGraphicsView中。平常的东西。我所做的就是画一棵树,分多个步骤,一级一步,每个节点都是我的自定义QGraphicsItem 这里是截图。在简单的情况下,树恰好是连续的 我首先画根节点。在用户输入字符串后触发的信号 void MainWindow::drawRootSlot(ConfigTreeBuilder & builder)//thi
QGraphicsItem
派生的自定义类(Configuration
),并将其对象添加到qgraphicscene
,然后将其显示在QGraphicsView
中。平常的东西。我所做的就是画一棵树,分多个步骤,一级一步,每个节点都是我的自定义QGraphicsItem
这里是截图。在简单的情况下,树恰好是连续的
我首先画根节点。在用户输入字符串后触发的信号
void MainWindow::drawRootSlot(ConfigTreeBuilder & builder)//this is a slot
{
c_scene->clear(); //the clear cause headache. i'll expain
Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(),builder.getNodesConfig());
//code
c_scene->addItem(conf);
//code
}
每个后续的配置
都绘制在另一个插槽中
void MainWindow::configTreeSlot(ConfigTreeBuilder & builder) //SLOT!!!
{
while(builder.chooseNextNode()) {
Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(), builder.getNodesConfig());
//code, while loop
QGraphicsLineItem *edge = c_scene->addLine(QLineF(*(parentsPoint), conf->getLeftOrigin()));
edge->setZValue(-1); //below the Configuration item
c_scene->addItem(conf);
}
}
第一次做的时候,一切都很好。当我输入一个新字符串,重置树时,黑暗魔法发生了。我期望它做的是:调用drawRootSlot()
,删除整个树(c\u scene->clear()
),绘制一个新的根节点。而且,如果我在drawRootSlot()
中放置一个调试器断点,就会发生这种情况!但当我运行它时(没有断点),我得到的是:
上一棵树已损坏,但未被删除。场景确实会清除其项目(打印的项目),但视图不会反映这一点。但同样,当我在drawRootSlot()
中放置断点时,视图和场景是同步的
我尝试删除场景对象,并安装一个新的场景对象,而不是调用c_scene->clear()
,以确保它为空。然后,更改将反映在视图上(第一次绘制始终有效)
所以,我不知道从这些症状中可以推断出什么。它与断点或freshhQGraphicscene
对象一样工作。仅使用c_scene->clear()
时不会出现这种情况。可以说我刚刚搞乱了父对象/子对象关系,但是clear()
确实从视图中删除了项。。。我试着在c\u scene->addItem()之后立即调用它
这是什么魔法?一个让我相信我并不愚蠢的人
EDIT:有趣的是,当调用c_scene->clear()
时,树的边缘(正常的qgraphicslneitem
s)在所有情况下都会被删除(断点与否)。与它们有关的东西不是自定义的吗?好的,在qgraphicscene::clear()之后调用QGraphicsView::viewport()。update()
解决了我的问题
但是有人对上述行为有解释吗
编辑:在做其他事情时,我无意中发现了问题的真正核心:我弄乱了GraphicItems的boundingRect()
,因此它位于可视项下方,只触及其下边缘(如屏幕截图所示,已被删除)。因此,现在不需要调用任何update()
方法。我认为,当您为graphicsview调用此方法时,它会清除前一个场景中保留的任何瑕疵的视图。您可以清除场景和图形视图
scene->clear();
ui->graphicsView->items().clear();
graphicsView=图形视图的名称
此代码将同时删除场景和图形视图