Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again
-
Hello,
here's a code sample:
auto myQGraphicsScene = new QGraphicsScene(); // ... auto myQWidget = new QWidget(); // ... myQGraphicsScene->addWidget(myQWidget); // ... myQGraphicsScene->clear(); // ... myQGraphicsScene->addWidget(myQWidget);I get a segmentation fault at the last line. What am I missing?
Thanks in advance for your input!
-
Hi,
The graphics scene takes ownership of the widget through theQGraphicsProxyWidgetobject returned byQGraphicsScene::addWidget. When you callQGraphicsScene::clearthe scene deletes all items (including your widget), somyQWidgetbecomes a dangling pointer. After that you pass a pointer that references an invalid memory location to theQGraphicsScene::addWidgetand ... voila! you get a segfault. -
Hi,
The graphics scene takes ownership of the widget through theQGraphicsProxyWidgetobject returned byQGraphicsScene::addWidget. When you callQGraphicsScene::clearthe scene deletes all items (including your widget), somyQWidgetbecomes a dangling pointer. After that you pass a pointer that references an invalid memory location to theQGraphicsScene::addWidgetand ... voila! you get a segfault.Thank you for the reply. To solve this tidily, could you please confirm that the following is efficient:
For every QWidget added to the QGraphicsScene this way:
- Remove it from the QGraphicsScene thanks to
QGraphicsScene::removeItem. deleteits QGraphicsProxyWidget afterward.
Is anything else required? Do I need to set the QWidget's parent to
nullptror anything else before adding it to the QGraphicsScene again? - Remove it from the QGraphicsScene thanks to
-
Thank you for the reply. To solve this tidily, could you please confirm that the following is efficient:
For every QWidget added to the QGraphicsScene this way:
- Remove it from the QGraphicsScene thanks to
QGraphicsScene::removeItem. deleteits QGraphicsProxyWidget afterward.
Is anything else required? Do I need to set the QWidget's parent to
nullptror anything else before adding it to the QGraphicsScene again?@Pippin said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
Is anything else required?
No, this should be just enough.
Do I need to set the QWidget's parent to nullptr or anything else before adding it to the QGraphicsScene again?
Nope, Qt should have done that for you when you removed the item from the scene.
- Remove it from the QGraphicsScene thanks to
-
@Pippin said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
Is anything else required?
No, this should be just enough.
Do I need to set the QWidget's parent to nullptr or anything else before adding it to the QGraphicsScene again?
Nope, Qt should have done that for you when you removed the item from the scene.
@kshegunov said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
Nope, Qt should have done that for you when you removed the item from the scene.
Well technically I didn't remove the QWidget, but its QGraphicsProxyWidget. At this point, both QWidget's and QGraphicsProxyWidget's parent is
nullptrthen, correct? -
@kshegunov said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
Nope, Qt should have done that for you when you removed the item from the scene.
Well technically I didn't remove the QWidget, but its QGraphicsProxyWidget. At this point, both QWidget's and QGraphicsProxyWidget's parent is
nullptrthen, correct?@Pippin said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
Well technically I didn't remove the QWidget, but its QGraphicsProxyWidget. At this point, both QWidget's and QGraphicsProxyWidget's parent is nullptr then, correct?
I can't say for sure without actually testing it out, but you should get a
QWidgetthat has a parentQGraphicsProxyWidget. Whereas theQGraphicsProxyWidgetshould have no parent. -
@kshegunov So this is the function I've been using:
void freeWidget(QWidget* foo) { const auto proxy = foo->graphicsProxyWidget(); myClass::myStaticQGraphicsScene->removeItem(proxy); foo->setParent(nullptr); delete proxy; }But even after that, when I add the QWidget again to
myClass::myStaticQGraphicsScene, I get a segmentation fault. Sometimes the following message is printed shorty before:QGraphicsProxyWidget::setWidget: cannot embed widget 0x247f680; already embeddedAny insight?
-
I apologize but I'd like to bump this. Is there a way to set a Widget's QGraphicsProxyWidget to
nullptras well? Clearly what I'm doing isn't enough.Solved: Indeed I had to set the Widget's QGraphicsProxyWidget to
nullptrbut the tricky part is, you can only do that from the QGraphicsProxyWidget, not from the QWidget. Here's the fixedfreeWidgetfunction:void freeWidget(QWidget* foo) { const auto proxy = foo->graphicsProxyWidget(); myClass::myStaticQGraphicsScene->removeItem(proxy); proxy->setWidget(nullptr); foo->setParent(nullptr); delete proxy; }Thanks again @kshegunov for your help yesterday.
(Edit: it seems that
foo->setParent(nullptr);is useless.) -
I apologize but I'd like to bump this. Is there a way to set a Widget's QGraphicsProxyWidget to
nullptras well? Clearly what I'm doing isn't enough.Solved: Indeed I had to set the Widget's QGraphicsProxyWidget to
nullptrbut the tricky part is, you can only do that from the QGraphicsProxyWidget, not from the QWidget. Here's the fixedfreeWidgetfunction:void freeWidget(QWidget* foo) { const auto proxy = foo->graphicsProxyWidget(); myClass::myStaticQGraphicsScene->removeItem(proxy); proxy->setWidget(nullptr); foo->setParent(nullptr); delete proxy; }Thanks again @kshegunov for your help yesterday.
(Edit: it seems that
foo->setParent(nullptr);is useless.)Thanks for posting the solution.
@Pippin said in Adding a QWidget to a QGraphicsScene, clearing it, then adding the QWidget again:
it seems that foo->setParent(nullptr); is useles
proxy->setWidget(nullptr);will set the widget's parent to null for you, yes.
-
I apologize but I'd like to bump this. Is there a way to set a Widget's QGraphicsProxyWidget to
nullptras well? Clearly what I'm doing isn't enough.Solved: Indeed I had to set the Widget's QGraphicsProxyWidget to
nullptrbut the tricky part is, you can only do that from the QGraphicsProxyWidget, not from the QWidget. Here's the fixedfreeWidgetfunction:void freeWidget(QWidget* foo) { const auto proxy = foo->graphicsProxyWidget(); myClass::myStaticQGraphicsScene->removeItem(proxy); proxy->setWidget(nullptr); foo->setParent(nullptr); delete proxy; }Thanks again @kshegunov for your help yesterday.
(Edit: it seems that
foo->setParent(nullptr);is useless.)@Pippin You are the best!!!! It's work!
-
J JoeCFD referenced this topic on
-
S SPlatten referenced this topic on