[partly solved] Problem mit QSortFilterProxy / Optimierung

Alles rund um die Programmierung mit Qt
Antworten
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

[partly solved] Problem mit QSortFilterProxy / Optimierung

Beitrag von padreigh »

Ich habe Datensätze die (vereinfacht) so aussehen:

Code: Alles auswählen

- Datenbank1
        - Exp1
                - Ina
                        - Trial01
                                - Mod1
                                - Mod usw
                        - Trial02
                                - Mod usw
                        - Trial usw
                - Subjects usw
        - Exp usw
- Datenbank usw
Ich fülle ein eigenes QAbstractItemModel mit den Daten aus einer DB, es sind
  • ca 5 Datenbank-nodes
    ca 10-30 Experimente je Datenbank
    ca 10-40 Subjekte je Experiment
    ca 1-20 Trials je Subjekt
    ca 2-6 Modalitäten je Trial
Ich möchte dem User eine Filterung anbieten, habe dazu das QSortFilterProxyModel gewählt. Mein Problem: Der User soll zB "Ina" eingeben und nun alles angezeigt bekommen was "auf dem Weg zu" Ina liegt und (ungefiltert) alles was unterhalb von "Ina" liegt (wahlweise Volltextsuche/QRegExp). Im obigen Beispiel (wenn sonst nirgends Ina vorkommt) also:

Code: Alles auswählen

- Datenbank1
        - Exp1
                - Ina
                        - Trial01
                                - Mod1
                                - Mod usw
                        - Trial02
                                - Mod usw
                        - Trial usw
Mein Ansatz erreicht das, allerdings nur dadurch das quasi jedes Element bei nicht eintreffen des Suchkriteriums solange (Kindes-)Kinder testet bis alle nicht erfüllt sind oder eines erfüllt ist. Erfüllt ein Item die Suchkriterien werden die QModelIndex'es aller parents sowie aller Kinder und Kindeskinder in ein QSet gesteckt. filterAcceptsRow() testet ob der derzeitige Index schon im Set ist, wenn ja wird die das item gezeigt, sonst getestet, alle Kinder getestet und ggf. nicht gezeigt.
Problem dabei: ich halte im Worstcase jeden vorhandenen QModelIndexes im QSet vorrätig ... die ich ja eigentlich nur in der Filterphase des QSortFilterProxyModels brauche ...

Geht das nicht besser?
Dateianhänge
sortfilter.zip
Kompilierbares (Qt 4.6) Widget mit QTreeView, automatisch befülltem QStandardModel und QSortFilterProxyModel sowie Sucheingabefeld/Knöpfen (auch für simple RegExp) im Anhang
(4.01 KiB) 113-mal heruntergeladen
Zuletzt geändert von padreigh am 14. September 2010 16:48, insgesamt 1-mal geändert.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Paar Änderungen ... wird schon schneller

Beitrag von padreigh »

Statt bei einem (dem Suchausdruck genügenden) QModelIndex alle parents bis zur Wurzel und alle (Kindes-)Kinder ins QSet<QModelIndex> validOnes zu packen, merke ich mir nur den entsprechenden Index.

In filterAcceptsRow() lasse ich 2 Methoden auf den aktuellen Index los:_
1) eine prüft ob der aktuelle index ein Child eines bereits validen Indexes ist, dann wird dieser Index auch akzeptiert
2) die andere prüft ob dieser Index ein parent eines der bereits als valide geprüften Indizes is, dann ist er auch valide

bei 2) war ich mir unsicher ob das überhaupt nötig ist ... falls QSortFilterProxyModel beim Filtern top-down geht, ist das überflüssig. Habe darum mal ein paar qDebugs hinzugefügt und das scheint tatsächlich der Fall zu sein. Hab mal alles rauskommentiert was zu 2) gehört und es tut immer noch ... und ist deutlich schneller. Der Worstcase-Speicher des QSets ist auch deutlich besser (oder sagen wir mal die QRegExps die mir einfallen und zum WorstCase führen sollen sind nicht mehr so einfach (.*) liefert die Anzahl der root-nodes und (^\d+$) die Anzahl der modal-nodes (wenn modal nodes die einzigen sind die aus reinen Zahlen bestehen) und beides ist kleiner als 44100.

Geht da noch was?
Dateianhänge
sortfilterV3.zip
Dickeres Model zum Testen (~40100 items). Unnützes auskommentiert.
(4.52 KiB) 129-mal heruntergeladen
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Antworten