Seite 1 von 1
Model: Sortieren nach zwei Spalten
Verfasst: 31. Januar 2013 20:07
von markusd112
Hallo,
ich habe eine QSqlTableModel und möchte es nach zwei Spalten gleichzeitig sortieren.
Hierfür möchte ich ein QSortFilterProxyModel dazwischenschalten, das ich zu einer eigenen Klasse abgeleitet habe.
Zum Sortieren nach beiden Spalten muss ich nach meinem Verständnis nun die Methode "lessThan" anpassen. Als Parameter wird "left" und "right" übergeben, jeweils ein QModelIndex.
Ich stehe auf dem Schlauch: wie genau komme ich an die beiden Werte der zwei für den "lessThan"-Vergleich zu verwendenden Spalten?
Danke & Gruß
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 1. Februar 2013 11:07
von markusd112
Hallo nochmal,
um es mal an einem Beispiel zu verdeutlichen:
ich habe eine sqlite3-Tabelel "tab_Artikel" mit folgendem Inhalt:
Auto_ID; Kategorie; ID; Bezeichnung;Preis
1; S; 3; Vollmilchschoko; 1,99 EUR
2; S; 2; Zartbitterschoko; 1,50 EUR
3; G; 5; Rotwein; 4,99 EUR
4; G; 3; Weißwein; 4,99 EUR
5; S; 10; Haselnussschoko; 1,79 EUR
Die Spalten "Kategorie" und "ID" ergeben zusammengenommen einen Produktcode (z.B. "S 1"). Die Daten sollen in einer TableView sortiert nach dem Produktcode angezeigt werden, also in der folgenden Reihenfolge:
G3
G5
S2
S3
S10
Ich muss es also irgendwie hinbekommen, dass mein Model die Daten nach der Spalte "Kategorie" und "ID" sortiert...
Gruß
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 1. Februar 2013 13:39
von Christian81
In der von QSortFilterProxyModel abgeleiteten Klasse hast du doch Zugriff auf die Daten deines Models. Wo ist also das Problem?
Re: Model: Sortieren nach zwei Spalten
Verfasst: 1. Februar 2013 15:40
von markusd112
Hallo,
ich kapier irgendwie nicht, wie ich über den QModelIndex Left & Right auf die beiden Spalten "id" und "Kategorie" zugreifen kann... Irgendwie stehe ich auf dem Schlauch....
In den ganzen Tutorials sind die Beispiele ja relativ überschaubar. Da reicht es, wenn man über left->data und right->data dann einen Textwert ausliest und die beiden dann vergleicht, um zu entscheiden welches der größere Wert ist. Aber wie komme ich z.B. an die anderen Spalten?
Wahrscheinlich ist die Lösung trivial, aber ich komme irgendwie nicht drauf...
Viele Grüße
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 1. Februar 2013 16:06
von Christian81
So wie Du normal auch auf Daten deines Models zugreifst - mit data():
http://qt-project.org/doc/qt-4.8/qabstr ... .html#data
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 07:18
von markusd112
Hallo,
Danke für den Tipp. Ich glaube, ich habe jetzt ungefähr verstanden, wie ich an die Sach rangehen muss: ich ermittle von den beiden übergebenen Parametern "left" und "right" die Zeile und greife dann über das in QModelIndex hinterlegte SourceModel auf die gewünschten Spalten der ermittelten Zeilen zu:
Code: Alles auswählen
int row1 = left.row();
int row2 = right.row();
int id1 = sourceModel()->index(row1,9,QModelIndex()).data().Int;
int id2 = sourceModel()->index(row2,9,QModelIndex()).data().Int;
QVariant kat1 = sourceModel()->index(row1,0,QModelIndex()).data();
QVariant kat2 = sourceModel()->index(row2,0,QModelIndex()).data();
if (kat1.String<kat2.String) {return true;} else
if (kat1.String>kat2.String) {return false;} else
if (id1<id2) {return true;} else {return true;};
Die Frage ist nun: wie ermittle ich, in welcher Model-Spalte die gewünschte SQL-Spalte "id" und "Kategorie" verborgen ist? Wäre es ein QSqlTableModel könnte ich das über fieldIndex(Feldname) ermitteln. Das hinterlegt SourceModel ist aber ein QAbstracItemModel, da gibt's diese Methode nicht...
Gruß
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 08:31
von Christian81
Da Du das Model selbst füllst, wirst Du wohl auch wissen wo welche Daten sind.
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 09:12
von markusd112
Hallo,
ich nutze ein QSqlTableModel. Dem übergibt man einfach den Namen der Datenbank-Tabelle und den Rest erledigt die Klasse... Ich habe also keine Chance selber festzulegen, welche Datenbankspalte in welcher Model-Spalte steht.Insbesondere, wenn es später mal Änderungen an der Datenbankstruktur gibt, kann sich die Reihenfolge auch durchaus ändern. Beim Verknüpfen der Eingabe-Widgets über den QDataWidgetMapper arbeite ich deshalb über die Methode fieldIndex und ermittle über den Sql-Spaltennamen die Model-Spalte.
Diese Methode gibt's aber im QSortFilterProxyModel nicht... Oder kann ich davon ausgehen, dass die Spalten-Indizes identisch zu meinem QSqlTableModel sind, weil ja dieses als Source-Model angegeben habe? Dann könnte ich ja die fieldIndex-Werte der abgeleiteten QSortFilterProxyModel-Klasse übergeben...
Viele Grüße
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 09:39
von Christian81
Und warum machst Du es im ProxyModel nicht genauso? Dort hast Du doch Zugriff auf das SourceModel (welches dein QSqltableModel ist) ...
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 10:03
von markusd112
Christian81 hat geschrieben:Und warum machst Du es im ProxyModel nicht genauso? Dort hast Du doch Zugriff auf das SourceModel (welches dein QSqltableModel ist) ...
Weil er mir dann sagt, dass fieldIndex keine Methode der Klasse QAbstractItemModel ist:
Fehler:
Code: Alles auswählen
'class QAbstractItemModel' has no member named 'fieldIndex'
Hmmmm....
Gruß
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 10:54
von markusd112
Hallo,
ich glaube, jetzt bin ich auf dem richtigen Weg: über Typ-Casting wandle ich das einfach wieder ein QSqlTableModel um:
Code: Alles auswählen
QSqlTableModel * x = qobject_cast<QSqlTableModel *>(this->sourceModel());
Gruß
Markus
Re: Model: Sortieren nach zwei Spalten
Verfasst: 2. Februar 2013 11:06
von Christian81
So ists korrektes C++, ja

Re: Model: Sortieren nach zwei Spalten
Verfasst: 3. Februar 2013 09:22
von markusd112
Hallo,
als "Doku", falls mal später jemand das gleiche Problem stolpert: ich hatte gedacht, die an lessThan übergebenen Indizes beziehen sich auf das ProxyModel, aber sie beziehen sich auf das sourceModel. Insofern braucht man hier nicht über mapToSource zu gehen.
Gruß
Markus