Model: Sortieren nach zwei Spalten

Alles rund um die Programmierung mit Qt
Antworten
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Model: Sortieren nach zwei Spalten

Beitrag 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
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Model: Sortieren nach zwei Spalten

Beitrag von Christian81 »

In der von QSortFilterProxyModel abgeleiteten Klasse hast du doch Zugriff auf die Daten deines Models. Wo ist also das Problem?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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... :wink:

Viele Grüße

Markus
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Model: Sortieren nach zwei Spalten

Beitrag von Christian81 »

Da Du das Model selbst füllst, wirst Du wohl auch wissen wo welche Daten sind.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Model: Sortieren nach zwei Spalten

Beitrag von Christian81 »

Und warum machst Du es im ProxyModel nicht genauso? Dort hast Du doch Zugriff auf das SourceModel (welches dein QSqltableModel ist) ...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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:

Code: Alles auswählen

int i = this->sourceModel()->fieldIndex("id");
Fehler:

Code: Alles auswählen

'class QAbstractItemModel' has no member named 'fieldIndex'
Hmmmm....

Gruß
Markus
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Model: Sortieren nach zwei Spalten

Beitrag von Christian81 »

So ists korrektes C++, ja :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
markusd112
Beiträge: 33
Registriert: 30. Dezember 2012 18:25

Re: Model: Sortieren nach zwei Spalten

Beitrag 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
Antworten