QSortFilterProxyModel Problem

Alles rund um die Programmierung mit Qt
Antworten
philistion
Beiträge: 22
Registriert: 8. Februar 2010 09:37

QSortFilterProxyModel Problem

Beitrag von philistion »

Hallo,

ich habe ein Problem mit einer von mir abgeleiteteten QSortFilterProxyModel-Klasse, welche ich zum Filtern von Datensätzen verwenden möchte. Folgende Funktionen habe ich implementiert:

Code: Alles auswählen

bool ExtFilterProxyModel::filterAcceptsRow(int sourceRow,
            const QModelIndex &sourceParent)
{
    if(doFiltering)
    {
        QModelIndex theIndex = sourceModel()->index(sourceRow, 0, sourceParent);
        QDateTime dt = sourceModel()->data(theIndex).toDateTime();
        return dateInRange(dt);
    }
    else
        return true;
}
Dann gibt es noch die Implementierung von dateInRange, die auch eine falsche Eingabe des Datums ausräumen soll:

Code: Alles auswählen

bool ExtFilterProxyModel::dateInRange(QDateTime &date)
{
    return ((!minDate.isValid() || (date > minDate))
            && (!maxDate.isValid() || (date < maxDate)));
}
Sowie natürlich kleine Routinen zum Setzen von minDate, maxDate, und von doFiltering.

Wenn ich nun aber doFiltering auf true setze, sind plötzlich alle Datensätz meiner Datenbank aus dem QTableView verschwunden, obwohl eigentlich nur jene weg sein sollten, die ich mit minDate und maxDate ausgegrenzt habe.

Könnt Ihr irgendeinen Fehler entdecken?

Das Datum befindet sich in der ersten Spalte des Models, deshalb wählte ich den Index 0. Muss ich vielleicht noch mit mapFromSource o.ä. arbeiten, um den QModelIndex zu "korrigieren"? (Obwohl mir das unlogisch erscheinen würde, da ich ja schon auf das sourceModel() zugreife..)

Ich hoffe jemand von euch kann mir weiter helfen. Danke!
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Beitrag von archer »

Ich verstehe das ! nicht vor minDate und maxDate.
Wenn minDate bzw. maxDate nicht gültig sind gibst du true zurück?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

::Glaskugel an::

Er hat 2 Datumfelder (min+max) und wenn man da ein valides Datum einträgt soll das Datum validiert werden, bei invalider Eingabe nicht ... das macht schon Sinn, wobei ich wohl >= und <= wählen würde ... es gibt da noch ein paar Merkwürdigkeiten wenn du ein QDateTimeEdit dafür nutzt ... da solltest du evtl. die Stunden auf 0:0:0:001 (für >=) und 23:59:59:999 (für <=) setzten.

Erwähnte ich schon wie toll die Examples sind?

http://doc.qt.nokia.com/4.6/itemviews-c ... model.html

schau dir mal die Implementierung (des ProxySortFilterModels) an ... da sortieren und evaluieren die auch nach Datum :D
Zuletzt geändert von padreigh am 17. August 2010 12:52, insgesamt 1-mal geändert.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

padreigh hat geschrieben:... es gibt da noch ein paar prelikularitäten wenn du ein QDateTime hast ...
:shock:
Was ist das?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Du bist zu schnell :D Hab mich auch gerade gefragt ob das ein Wort ist ... bedeutet sowas wie "Sachen die man vorher beachten sollte" ... aber ich hab da irgendwie nicht die richtigen Buchstaben in der Richtigen Reihenfolgen drin ;) daher grad wieder rauseditiert

... ich suchte das hier: http://www.thefreedictionary.com/preliminaries
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
philistion
Beiträge: 22
Registriert: 8. Februar 2010 09:37

Beitrag von philistion »

Hallo,

Danke für die Antworten, aber aus eben jenen Beispielen habe ich meinen Code übernommen bzw. nur minimal modifiziert. An was könnte es ansonsten liegen?

Ich habe die Beispiele nur folgendermaßen verändert.
- QDate ist bei mir ein QDateTime, sollte aber an den Vergleichen, usw. nichts ändern , oder?
- Habe alle sonstigen Überprüfungen rausgenommen, ich gehe nur nach der ersten Spalte, wo sich der Unix Timestamp befindet.

Da fällt mir ein, könnte das das Problem sein? Ich speichere in der Datenbank nur den Unix Timestamp und wandle das ganze erst in einem Delegate in ein lesbares Datum um.
Könnte dies mit QVariant::toDateTime() nicht korrekt gewandelt werden?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

philistion hat geschrieben:Da fällt mir ein, könnte das das Problem sein? Ich speichere in der Datenbank nur den Unix Timestamp und wandle das ganze erst in einem Delegate in ein lesbares Datum um.
Könnte dies mit QVariant::toDateTime() nicht korrekt gewandelt werden?
Klar kann es daran liegen. Du solltest vor einem "casten" des QVariant mit canConvert() prüfen, ob die Konvertierung überhaupt gut geht. QDateTime hat auch ein "isValid()", es kann sein, dass du da lauter ungültige QVariants liegen hast.
Wenn du aber deinen QVariant über die SqlQueries bekommst, und die Datenbanktabelle ordentlich aufgesetzt ist (der Typ jener Spalte also "datetime" ist) sollte auch "toDateTime()" einen korrekten Wert liefern.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Da fällt mir ein, könnte das das Problem sein? Ich speichere in der Datenbank nur den Unix Timestamp und wandle das ganze erst in einem Delegate in ein lesbares Datum um.
Könnte dies mit QVariant::toDateTime() nicht korrekt gewandelt werden?
Als haben wir einen Int und nur für die Darstellung wird umgewandelt, also ist so auch kein Vergleich mit einem Datum möglich.

Also entweder bei der Query schon als Datum abfragen oder beim Vergleich in ein Datum konvertieren. (Oder gleich in der Datenbank als Datum speichern).
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Beitrag von ScyllaIllciz »

Ich denke Du suchst das hier:

Code: Alles auswählen

void QDateTime::setTime_t ( uint seconds )
philistion
Beiträge: 22
Registriert: 8. Februar 2010 09:37

Beitrag von philistion »

Vielen Dank, das war der Fehler. Nun funktioniert alles wie gewünscht :)

Das einzige Problem bleibt die Performance. Habt Ihr eine Idee wie man eine SQLite-Datenbank, auf die man mit einem QSqlQueryModel + QSortFilterProxy zugreift und auf einem QTableView anzeigt, schneller bekommt?

Welche Optimierungsmöglichkeiten stehen hier zur Verfügung? Es handelt sich nämlich um extrem viele Datensätze, wo liegt hier der Flaschenhals bzw. wo seht Ihr Potential zum Einsparen?

Wäre es sinnvoll, ein eigenes Model zu schreiben welches die Daten effektiv nachlädt oder macht das QSqlQueryModel dies schon effektiv genug, also eben nur jene Daten die angezeigt werden sowie alle angrenzenden in einen Cache laden?

Würde mich über konkrete Anregungen jeder Art freuen, Danke!
Antworten