Seite 1 von 1

Qt 3: QListVieItems löschen

Verfasst: 31. März 2006 17:09
von arne.anka
ich habe einen QListView mit mehreren einträgen, slection-mode ist "extended" und dazu einen qpushbutton zum löschen.
wenn ich mehrere einträge auswähle und den knopf drücke, sollen diese einträge gelöscht werden.
in der praxis stürzt mein programm aber sang- und klanglos ab.
mir ist nicht wirklich klar, was da passiert, aber ich habe mal auf signale getippt, die beim anfassen der Items emittiert werden udn also blockSignals(true) auf den listview gesetzt -- ändert nix.

kann mir wer tipps geben , was a) passiert und b) wie ich damit umgehe?
in den docs steht der schöne satz

"Note that changing the state of the list view in a slot connected to a list view signal may cause unexpected side effects. If you need to change the list view's state in response to a signal, use a single shot timer with a time out of 0, and connect this timer to a slot that modifies the list view's state. "

abgesehen davon, dass ich die signal ja explizit vorher abgeschaltet habe, ist mir der sinn von "use a single shot timer" völlig schleierhaft -- wenn ich ihn von meinem knopf aus in einem slot aufrufe, ändert das nix.

Code: Alles auswählen

//dieser slot ist an des buttons clicked-signal gebunden
void MyPage::slotDeleteLater(){
    QTimer::singleShot(0, this, SLOT(slotDelete()));
}

void MyPage::slotDelete(){
    //tCurrentList ist ausserhalb definiert als new QListView;
    tCurrentList->blockSignals(true);
    QListViewItemIterator it( tCurrentList, QListViewItemIterator::Selected );
    while ( it.current() ) {
        tCurrentList->takeItem(it.current());
        it++;
    }
    tCurrentList->blockSignals(false);
}

Verfasst: 3. April 2006 07:56
von macman
Du hast die takeItem-Methode nicht richtig verstanden, die gibt dir nämlich das nächste Item zurück. Lass das it++ weg, dann sollte es gehen.

Code: Alles auswählen

    while ( it.current() ) {
        it = tCurrentList->takeItem(it.current());
    }

Verfasst: 3. April 2006 09:31
von arne.anka
lt docu ist takeItem void, dh es gibt nix zurück -- wird durch die fehlermeldung bestätigt.
wenn ich

Code: Alles auswählen

delete it.current()
statt

Code: Alles auswählen

takeItem(it.current())
nehme, ändert das nix, es crasht trotzdem, wegen des folgen ganz offensichtlich.
bleibt also die frage, wie ich so ein item korrekt lösche ...

Verfasst: 3. April 2006 09:38
von arne.anka
ich habe es jetzt mal so probiert:

Code: Alles auswählen

void MyPage::slotDelete(){ 
    tCurrentList->blockSignals(true); 
    QListViewItemIterator it( tCurrentList, QListViewItemIterator::Selected ); 
    while ( it.current() ) { 
        QListViewItem *x=it.current(); 
        it++; 
        delete x;
    } 
    tCurrentList->blockSignals(false); 
}
und jetzt crasht's zumindest nichtmehr -- ganz überzeugt bin ich allerdings nicht. gibt es da doch noch was intelligenteres?
bzw was spricht für takeItem() statt delete?

Verfasst: 3. April 2006 09:45
von macman
arne.anka hat geschrieben:lt docu ist takeItem void, dh es gibt nix zurück -- wird durch die fehlermeldung bestätigt.
Hmm, hatte ich wohl falsch in Erinnerung. Hier mal meine Methode aus einem älteren Qt3 Projekt, mit der ich selektierte Einträge aus einer Listview entferne.

Code: Alles auswählen

	QListViewItemIterator it(currlv);

	while (it.current()) 
	{
		if (it.current()->isSelected())
			currlv->takeItem(it.current());
		else
			it++;
	}

Verfasst: 3. April 2006 10:08
von arne.anka
der interne pointer auf curr wird wohl weitergesetzt.

Code: Alles auswählen

if (it.current()->isSelected())
das sollte mir ja das flag

Code: Alles auswählen

QListViewItemIterator::Selected
schon vorsortieren.

wenn ich jetzt mal spasseshalber analog bastele

Code: Alles auswählen

QListViewItemIterator it( tCurrentList, QListViewItemIterator::Selected );
while ( it.current() ) {
    tCurrentList->takeItem(it.current());
}
wird mir die _komplette_ liste gelöscht, nicht nur die selektierten items -- und ich bekomme eine meldung "curr out of sync" von qt.
übernehme ich exakt deine konstruktion, klappts.