Seite 1 von 1
QGraphicsProxyWidget aus QGraphicsScene löschen
Verfasst: 19. Januar 2010 18:21
von Psychomax
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
Verfasst: 19. Januar 2010 18:30
von AuE
Ähm.... mit elchen Code hast es denn gemacht? Kurzes sample?
Verfasst: 19. Januar 2010 18:56
von Psychomax
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();
}
Ja das wäre eventuell hilfreich. Vielleicht auch noch was zum Hintergrund. Ich habe jede Menge QWidgets, die mittels einen Automaten verknüpft sind. Für das Anzeigen wollte ich mit eine Engine bauen. (Um später auch mal beim Wechsel Effekte hinzu zu fügen.)
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.
Verfasst: 19. Januar 2010 18:58
von Psychomax
Aso. Das Löschen funktioniert so weit, dass das Widget nicht mehr angezeigt wird. Allerdings bekomme ich dennoch das Warning, dass das Widget vorhanden ist.
Verfasst: 19. Januar 2010 19:23
von solarix
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:
Code: Alles auswählen
switch (_state) {
case StateA:
_proxyA->show(); _proxyB->hide(); break;
case StateB:
_proxyA->hide(); _proxyB->show(); break;
...
}
Ich habe keine Erfahrung in der QGraphicsView, aber wäre sowas nicht effizienter?
Verfasst: 19. Januar 2010 19:59
von Psychomax
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();
auch wenn nur das in der Methode steht bekomm ich folgenden Fehler.
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;
Also ich kann kurz um, dass GraphicsItem aus der Scene löschen aber nicht aus dem Proxy. Trotz eines delete proxy.
@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!

Verfasst: 20. Januar 2010 11:06
von Psychomax
So ich hab jetzt nochmal in Ruhe den Code aufgelöst. Fakt ist, wenn ich das Proxy Objekt lösche, es auch mein Widget löscht. Doof ist das, aber ist halt so. Muss ich mir jetzt eine andere Strategie überlegen! Trotzdem danke!!!
