Löschen von selektierten Items während MouseMove -> Crash

Alles rund um die Programmierung mit Qt
Antworten
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Löschen von selektierten Items während MouseMove -> Crash

Beitrag von mikemc »

Hallo ihr,

Ich habe QGraphicsItems mit Flag ItemIsMovable == true , und einige mit == false, beide aber selektierbar.

Wenn ein verschiebbares Item verschoben wird und zugleich nicht verschiebbare Items selektiert sind kommt es zum Crash bei QGraphicsItem::mouseMoveEvent, da QT in dieser Routine am Anfang alle selektierten Objekte in eine Liste schmeisst und dann in einer Schleife nach und nach durchgeht ohne Rücksicht, ob denn nicht das Item inzwischen gelöscht wurde.

Da ich aber beim Verschieben von beweglichen Items, andere Items während des Verschiebens lösche kommt es zum Absturz

Weiss jemand ein Problem für meine Lösung?

lg Michael
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Löschen von selektierten Items während MouseMove -> C

Beitrag von franzf »

mikemc hat geschrieben:Weiss jemand ein Problem für meine Lösung?
Das ist hoffentlich nicht ernst gemeint :D

Ansonsten sichergehen, dass Qt es nicht mehr als selektiert hält:
http://qt.nokia.com/doc/4.6/qgraphicsit ... etSelected
Also etwa so:

Code: Alles auswählen

item->setSelected(false);
delete item;
Vllt. vorher noch aus der Scene entfernen.
Letzteres sollte eigentlich helfen, da ich denke bei Nokia sitzen keine Trottel, die werden schon verhindern dass ein Item, sobald es nicht mehr in der Scene ist, nocht verwendet wird...
Falls nicht kannst du schauen ob es was bringt von QGraphicsObject abzuleiten und item->deleteLater();, damit in dieser Eventloop-Runde nichts böses mehr mit dem Item geschehen kann.

Sollte das immer noch nicht helfen -> Bugreport!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Pack alle deine zu löchenden Items in eine Liste (event. gleich noch eine hide() darauf)

Überschreib QGraphicsScene::event und lösch dort deine Items.
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag von mikemc »

Das ist hoffentlich nicht ernst gemeint
hallo franzf,
ernster als Ernst :)
Vllt. vorher noch aus der Scene entfernen.
das passiert eh :)
die werden schon verhindern dass ein Item, sobald es nicht mehr in der Scene ist, noch verwendet wird...
daran zweifle ich sehr...
kannst du schauen ob es was bringt von QGraphicsObject abzuleiten und item->deleteLater();
wenns nicht anders geht vlcht eine variante, allerdings möchte ich möglichst vermeiden ein QGraphicsObject für jedes QGraphicsItem zu verwenden, da ich sehr viele Objekte in der Scene habe
Pack alle deine zu löchenden Items in eine Liste (event. gleich noch eine hide() darauf)

Überschreib QGraphicsScene::event und lösch dort deine Items.
Hallo upsala,
guter tipp,
problem ist, dass QGraphicsScene::event() vor QGraphicsScene::mouseMoveEvent aufgerufen wird
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

problem ist, dass QGraphicsScene::event() vor QGraphicsScene::mouseMoveEvent aufgerufen wird
Und?
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag von mikemc »

@upsala
Folgende Reihenfolge:
QGraphicsScene::event()
QGraphicsScene::mouseMoveEvent()
QGraphicsItem::itemChange() <--- hier werden Objekte gelöscht
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

@mikemc
Dann wollen wir das ganze mal schön verschachtelt malen:

Code: Alles auswählen

QGraphicsScene::event() {
  //*)
  QGraphicsScene::mouseMoveEvent() {
    QGraphicsItem::itemChange() {
      // hier werden Objekte in die Liste eingetragen
    }
  }
  //und hier werden die Elemente der Liste gelöscht...
}
*) Hier könnte man auch löschen...
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag von mikemc »

OK , aber könnte ich nicht auf QGraphicsScene::event() mit einer vererbten Scene verzicheten?

QMeineScene::mouseMoveEvent()
{
QGraphicsScene::mouseMoveEvent():
QGraphicsItem::itemChange()
//Jetzt Objekte löschen
}

Habs mal mit deleteLater() probiert, bis jetzt kein Absturz...
Antworten