Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit for-schleifen-Inkonsistenz



Mat
13-11-2005, 01:59
Hallo,
ich habe ein QTable in welchem der user wahlweise unterschiedliche zeilen löschen darf.
Er kann z,B auch nur Zeile 1 und 5 löschen.

Mein Problem besteht nun darin dass ich nicht einfach durch die ganze Tabelle gehen kann und alles was selektiert ist löschen darf...denn dadurch verliere ich die Konsistenz in der for-schleife...



QTable* tmp = new QTable(table->numRows(),table->numCols());
for(int i = 0; i < tmp_table->numRows();i++)
if(table->isRowSelected(i,TRUE))
table->removeRow(i);


ich habe dann als nächstes vresucht mit QMemArray zu arbeiten aber auch da ohne Erfolg:



QMemArray<int> arr(table->numRows());
QMemArray<int> tmp_arr = arr.copy();
for(uint i =0; i < tmp_arr.size(); i++)
{
if(table->isRowSelected(i,TRUE)) arr[i] = i;
else arr.truncate(i);
}
table->removeRows(arr);


Nun weiß ich nicht mehr so genau weiter...ich könnte mir einen Hash sozusagen aufbauen mit true/false flags mit den Zeilennummern als key aber ich glaube das geht doch bestimmt einfacher oder nicht ???
Danke für eure Ideen...

BeS
13-11-2005, 02:10
Hallo,
ich habe jetzt nicht so die Erfahrung mit QTable, aber ich denke mal dein Problem ist, dass die for Schleife bei jedem Durchlauf i erhöht, wenn aber eine Zeile gelöscht wurde rutschen alle anderen auf und i sollte daher nicht erhöht werden. Lösung: while-Schleife:



QTable* tmp = new QTable(table->numRows(),table->numCols());
int i = 0;
while(i < tmp_table->numRows())
if(table->isRowSelected(i,TRUE))
table->removeRow(i);
else
i++;

Mat
13-11-2005, 02:32
hmm...leider funktioniert das auch nicht....

Kirsche
13-11-2005, 08:45
Hallo Mat,

ich glaube, der Weg über ein Array ist schon ganz gut.
Vielleicht geht es so:

QMemArray<int> arr( table->numSelections () ); // Anzahl der Selektionen
int index = 0;

for(uint i =0; i < table->numRows(); i++)
{
if(table->isRowSelected(i,TRUE))
{
arr[index] = i;
index++;
}
}
table->removeRows(arr);

Falls table->numSelections() nicht das liefert, was du brauchst, müsstest du vorher einmal über die Tabelle laufen und die Anzahl der Zeilen bestimmen, die selektiert sind.

Ansonsten geht vielleicht auch:

QMemArray<int> arr(table->numRows());
int index = 0;

for(uint i =0; i < table->numRows(); i++)
{
if(table->isRowSelected(i,TRUE))
{
arr[index] = i;
index++;
}
}
arr.truncate(index); // vielleicht auch index plus oder minus 1
table->removeRows(arr);

Ich glaube, truncate(uint pos) löscht nicht einen Eintrag, sondern schneidet das Array an der angegebenen Stelle ab. Zuerst erhält das Array ja eine Größe, die in den meisten Fällen zu groß ist. Es werden nacheinander alle zu löschenden Zeilen eingetragen und anschließend alle leeren Elemente gelöscht, indem nach dem letzten Eintrag abgeschnitten wird.

Vielleicht geht auch removeSelection( const QTableSelection & s). Der Beschreibung nach hört es sich so an, als würden alle selektierten Bereiche gelöscht werden. Und das möchtest du doch, oder?

Schöne Grüße,

anda_skoa
13-11-2005, 13:41
Ansich sollte die von BeS vorgeschlagene Lösung auch funktionieren, aber wenn wie von Kirsche aufgezeigt QTable schon eine Methode anbietet, mit der man mehrere Zeilen auf einmal löschen kann, sollte man die nehmen.

Das ermöglicht QTable intern eventuelle Optimierungen zu machen, zB nur ein Update nachdem alle Zeilen entfernt wurden.

truncate(index)
bzw
resize(index)
sollte schon passen, denn index ist durch das ++ nach dem Einfügen des Wertes praktisch immer gleich der "Länge" der Daten.

Ciao,
_

Mat
13-11-2005, 22:45
danke. Immer wieder überraschend was man für klasse Hilfe bekommt. Funktioniert jetzt alles prima. Leuchtet mir auch ein jetzt.

Hoffentlich kann ich irgendwann in ferner Zukunftauch jemandem so helfen ;)