Seite 1 von 1

QSortFilterProxyModel Problem

Verfasst: 17. August 2010 10:55
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!

Verfasst: 17. August 2010 11:37
von archer
Ich verstehe das ! nicht vor minDate und maxDate.
Wenn minDate bzw. maxDate nicht gültig sind gibst du true zurück?

Verfasst: 17. August 2010 12:45
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

Verfasst: 17. August 2010 12:51
von franzf
padreigh hat geschrieben:... es gibt da noch ein paar prelikularitäten wenn du ein QDateTime hast ...
:shock:
Was ist das?

Verfasst: 17. August 2010 12:53
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

Verfasst: 17. August 2010 13:51
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?

Verfasst: 17. August 2010 14:33
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.

Verfasst: 17. August 2010 14:56
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).

Verfasst: 17. August 2010 17:09
von ScyllaIllciz
Ich denke Du suchst das hier:

Code: Alles auswählen

void QDateTime::setTime_t ( uint seconds )

Verfasst: 18. August 2010 13:12
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!