Hallo zusammen!
Dies würde ich gern machen. Liege ich richtig in der Annahme das ein QGraphicsItem auf den Proxy zeigt? Wenn ich nämlich den Zeiger aus der Scene lösche ist auch das Widget weg. Soweit genau das was ich will. Allerdings, wenn ich das Widget jetzt nochmal mittels addWidget() einfüge kommt folgender Fehler:
GraphicsProxyWidget::setWidget: cannot embed widget 0x88acb80; already embedded
Darauf hin habe ich versucht das GraphicsItem zu erst zu löschen und danach noch mal mittel delete das Proxy Widget. Anschließend das Widget wieder einzufügen. Leider ohne Erfolg. Denn das Programm hängt sich dann auf.
LG Max
QGraphicsProxyWidget aus QGraphicsScene löschen
Code: Alles auswählen
void ViewEngine::setSceneContent(QWidget *newC)
{
QList <QGraphicsItem*> items = this->scene->items(Qt::DescendingOrder);
if(newObj != NULL)
{
qDebug("HUHU");
if(items.contains(dynamic_cast <QGraphicsItem*> (oldProxyWidget)))
{
qDebug("deleteObj");
for(int i=0;i<items.count();i++)
{
qDebug("%d",i);
}
this->scene->removeItem(dynamic_cast <QGraphicsItem*> (oldProxyWidget));
}
oldObj = newObj;
oldProxyWidget = newProxyWidget;
}
newObj = newC;
newProxyWidget = this->scene->addWidget(newC);
this->animatedSwitchScene();
}
In meiner Scene sind sollen effektiv nur zwei Widgets sein. Eines das eingeblendet wird und eine was ausgeblendet wird. Lasse ich
this->scene->removeItem(dynamic_cast <QGraphicsItem*> (oldProxyWidget));
weg. Funktioniert das Programm wie gewünscht. Allerdings habe ich zwei Nachteile, die ich als kritisch empfinde. Zum einen bekomme ich immer die Fehlermeldung
QGraphicsProxyWidget::setWidget: cannot embed widget 0x93b4b08; already embedded
und die Liste der QGraphicsItem innerhalb der QGraphicsScene steigt stätig an.
das ganze ist etwas verwirren (keine Strategie bei der Vergabe von Variabelnbezeichner, unnötige this-Pointer, IMHO unnötige dynamic_casts, usw.), weswegen ich einfach ungeordnet ein paar Hinweise gebe:
1. Das Widget zeigt nicht auf den Proxy, sondern umgekehrt. Das Proxy "verwaltet" quasi das Child-Widget und gibt sich aus Sicht der View als normales "QGraphicsItem" aus.
2. Das Proxy wird bei "addWidget()" erstellt, weswegen bei jedem Durchgang immer mehr Proxies existieren.
3. du löscht nirgendwo was (weder ein Proxy noch ein Widget). Du entfernst es lediglich (remove... löscht keine Instanzen) aus der Scene.
4. Wenn du einmal ein Proxy hast (und dieses mit remove... entfernst), wäre es vermutlich besser, dieses Proxy wieder mit "addItem" einzufügen, als ein neues zu generieren...?
5. Von der Vorgehensweise her: wenn du einen Automaten nachbilden möchtest, ginge es denn nicht, die Unterschiedlichen Widgets einfach sichtbar/unsichtbar zu schalten? So im Stil:
Ich habe keine Erfahrung in der QGraphicsView, aber wäre sowas nicht effizienter?
1. Das Widget zeigt nicht auf den Proxy, sondern umgekehrt. Das Proxy "verwaltet" quasi das Child-Widget und gibt sich aus Sicht der View als normales "QGraphicsItem" aus.
2. Das Proxy wird bei "addWidget()" erstellt, weswegen bei jedem Durchgang immer mehr Proxies existieren.
3. du löscht nirgendwo was (weder ein Proxy noch ein Widget). Du entfernst es lediglich (remove... löscht keine Instanzen) aus der Scene.
4. Wenn du einmal ein Proxy hast (und dieses mit remove... entfernst), wäre es vermutlich besser, dieses Proxy wieder mit "addItem" einzufügen, als ein neues zu generieren...?
5. Von der Vorgehensweise her: wenn du einen Automaten nachbilden möchtest, ginge es denn nicht, die Unterschiedlichen Widgets einfach sichtbar/unsichtbar zu schalten? So im Stil:
Code: Alles auswählen
switch (_state) {
case StateA:
_proxyA->show(); _proxyB->hide(); break;
case StateB:
_proxyA->hide(); _proxyB->show(); break;
...
}
Code: Alles auswählen
newProxyWidget = this->scene->addWidget(newC);
this->scene->removeItem(dynamic_cast <QGraphicsItem*> (newProxyWidget));
newObj = newC;
newProxyWidget = this->scene->addWidget(newC);
this->animatedSwitchScene();
QGraphicsProxyWidget::setWidget: cannot embed widget 0x93b4b08; already embedded
Im Quellcode steht folgendes. Sprich wenn er die obige Fehlermeldung ausgibt, wird kein neues Widget erstellt. Auch wenn ich mittels delete den Proxy löschen möchte.
Code: Alles auswählen
// Register this proxy within the widget's private.
619
// ### This is a bit backdoorish
620
QWExtra *extra = newWidget->d_func()->extra;
621
if (!extra) {
622
newWidget->d_func()->createExtra();
623
extra = newWidget->d_func()->extra;
624
}
625
QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
626
if (*proxyWidget) {
627
if (*proxyWidget != q) {
628
qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p"
629
"; already embedded", newWidget);
630
}
631
return;
632
}
633
*proxyWidget = q;
@solarix
1. ja so hab ich das auch verstanden. Deswegen wollte ich auch das Proxy löschen.
Ich probiere morgen nochmal rum. Hab jetzt schon soviel im Code rumgemacht. Eventuell bringt eine Nacht Schlaf Besserung. Die Müdichkeit sieht man scheins schon in meinem Code!