Hallo
Seit knapp einer Woche arbeite ich nun mit QT4.5.2.
Ich möchte in einem QTreeView meine Windows Ordnerstruktur darstellen.
Allerdings sollen nicht alle Ordner und Unterordner angezeigt werden, sondern nur die Ordner die zu einem Ordner mit Namen „Test“ führen.
Z.B. Das ist die Ordnerstruktur:
C:
--Ordner1
--Ordner2
----Ordner 2.1
----Ordner 2.2
------Ordner XY
------Test
----Ordner 2.3
--Ordner3
D:
F:
H:
--Ordner1
----Test
----Ordner XYZ
--Ordner2
In meinem TreeView soll aber dann nur das angezeigt werden:
C:
--Ordner2
----Ordner 2.2
------Test
H:
--Ordner 1
----Test
Ich habe ein QFileSystemModel einer abgeleiteten Klasse von QSortFilterProxyModel zugewiesen und das QSortFilterProxyModel einem QTreeView zugewiesen.
Die Funktion filterAcceptsRow des QSortFilterProxyModel habe ich überschrieben und damit kann man ja auch bevor das TreeView angezeigt wird durch alle Knoten gehen und prüfen ob der Knoten "Test" heißt oder nicht, aber ich muss ja dann wieder zu den Elterknoten hoch um diese zuzulassen oder nicht.
Also möchte ich mein Model vor der Anzeige im TreeView durchgehen und prüfen ob es eben den Ordner "Test" gibt und mit Rückgabewerten an die Elternknoten entscheiden ob sie angezeigt werden müssen oder nicht.
Aber es gelingt mir nicht das QSortFilterProxyModel so zu durchlaufen.
Hat evtl jemand einen Tipp für mich?
Mit der Suche hab ich zwar einige Dinge gefunden, aber nichts was mir meiner Meinung nach bei meinem Problem weiterhelfen würde.
Grüße Yukirin
QTreeView mit QSortFilterProxyModell
Ich habe das so gemacht, vielleicht hilft es dir:
Code: Alles auswählen
//----------------------------------------------------------------------------------------
// filterAcceptsRow() [ protected ]
//----------------------------------------------------------------------------------------
/*!
* @brief Reihe filtern
*
* @param[in] aSourceRow - Reihe
* @param[in] acrSourceParent - Modell-Index
*
* @return @c true Anzeigen, @c false nicht anzeigen
*/
//----------------------------------------------------------------------------------------
bool MyProxyModel::filterAcceptsRow(
int aSourceRow,
const QModelIndex& acrSourceParent) const
{
if (filterRegExp().isEmpty() == true)
return true;
return search(sourceModel()->index(aSourceRow, 0, acrSourceParent));
}
//----------------------------------------------------------------------------------------
// search() [ protected ]
//----------------------------------------------------------------------------------------
/*!
* @brief Den Baum rekursiv durchgehen
*
* @param[in] acrSourceIndex - Index der überprüft wird
*
* @return @c true: Index anzeigen, @c false: nicht anzeigen
*/
//----------------------------------------------------------------------------------------
bool MyProxyModel::search(const QModelIndex& acrSourceIndex) const
{
if (acrSourceIndex.isValid())
{
QString itemValue("");
itemValue = sourceModel()->data(acrSourceIndex, Qt::DisplayRole).toString();
if (itemValue.contains(filterRegExp()) == true)
return true;
if (sourceModel()->hasChildren(acrSourceIndex) == true)
{
for (int i = 0; i < sourceModel()->rowCount(acrSourceIndex); i++)
{
QModelIndex idx(sourceModel()->index(i, 0, acrSourceIndex));
if (search(idx) == true)
return true;
}
}
}
return false;
}
DU kommst per "QAbstractItemModel * sourceModel () const" immer auf das Basis(Source)Model zurueck.
aus filterAcceptsRow heraus, solltest das BasisModel fragen, ob es subelemente hat .... und ob diese subelemente irgendwas mit dem namen "test" selber enthalten (rekursion!)
fuer das Abfragen sollstest dich gegenueber dem SourceModel verhalten wie nen View und die methoden des QAbstractItemModel - Interfaces verwenden.
ups, zu spaet
Archer macht es Sir ja wieder zu einfach
Ciao ....
aus filterAcceptsRow heraus, solltest das BasisModel fragen, ob es subelemente hat .... und ob diese subelemente irgendwas mit dem namen "test" selber enthalten (rekursion!)
fuer das Abfragen sollstest dich gegenueber dem SourceModel verhalten wie nen View und die methoden des QAbstractItemModel - Interfaces verwenden.
ups, zu spaet
Archer macht es Sir ja wieder zu einfach
Ciao ....
Hallo
Nun muss ich dazu doch noch mal ne Frage stellen.
Ich hab mir jetzt ne eigene Funktion geschrieben, die von „filterAcceptsRow()“ aufgerufen wird.
In dieser Funktion habe ich einen „const QModelIndex& Knoten“,
für den dann überprüft werden soll, ob es einen Unterknoten „Test“ gibt.
Ich rufe die Funktion „sourceModel()->hasChildren(Knoten)“ auf, die mir true zurückliefert und sagt, dass der Knoten Unterknoten hat. Wenn ich jetzt aber eine Zeile später die Funktion „sourceModel ()->rowCount(Knoten)“ aufrufe, sagt mir die Funktion das die Anzahl 0 ist.
So kann ich die Funktion also nicht noch mal für die Unterknoten aufrufen. Es ist mir nun aber absolut schleierhaft, warum die Funktion „rowCount()“ mir sagt, dass es keine Unterknoten gibt.
Habt ihr evtl eine Idee dazu?
Nun muss ich dazu doch noch mal ne Frage stellen.
Ich hab mir jetzt ne eigene Funktion geschrieben, die von „filterAcceptsRow()“ aufgerufen wird.
In dieser Funktion habe ich einen „const QModelIndex& Knoten“,
für den dann überprüft werden soll, ob es einen Unterknoten „Test“ gibt.
Ich rufe die Funktion „sourceModel()->hasChildren(Knoten)“ auf, die mir true zurückliefert und sagt, dass der Knoten Unterknoten hat. Wenn ich jetzt aber eine Zeile später die Funktion „sourceModel ()->rowCount(Knoten)“ aufrufe, sagt mir die Funktion das die Anzahl 0 ist.
So kann ich die Funktion also nicht noch mal für die Unterknoten aufrufen. Es ist mir nun aber absolut schleierhaft, warum die Funktion „rowCount()“ mir sagt, dass es keine Unterknoten gibt.
Habt ihr evtl eine Idee dazu?
Hallo
Ich habe mir die Doku zu dem QFileSystemModel angeschaut. Und das rowCount gibt dann wohl 0 zurück, weil ich es an einer Stelle aufrufe wo das Model noch mit Ordnern bestückt wird. Verstehe ich das richtig? Also muss ich meine Funktion zum Durchgehen der Ordner wann anders aufrufen.
FilterAcceptsRows wird ja aufgerufen bevor das TreeView angezeigt wird und da rufe ich dann auch meine Suchfunktion auf. Und das scheint ja kein guter Zeitpunkt zu sein. Aber wenn mein TreeView angezeigt wird, ist es schon zu spät nach den Ordnern zu suchen und zu filtern.
Ich hab es nun mit einem QDirModel statt eines QFileSystemModels probiert. Da funtkioniert das mit dem rowCount ja an der Stelle.
Aber das QFileSystemModel scheint ja schneller zu sein als das QDirModell.
Wenn ich das QDirModell verwende muss der Anwender ewig warten, bevor ihm das Fenster mit dem TreeView angezeigt wird.
Also möchte ich doch wieder auf QFileSystemModel umsteigen.
Aber wann muss ich denn dann meine Funktion aufrufen, damit rowCount nicht 0 anzeigt?
Ich bin ratlos.
Ich habe mir die Doku zu dem QFileSystemModel angeschaut. Und das rowCount gibt dann wohl 0 zurück, weil ich es an einer Stelle aufrufe wo das Model noch mit Ordnern bestückt wird. Verstehe ich das richtig? Also muss ich meine Funktion zum Durchgehen der Ordner wann anders aufrufen.
FilterAcceptsRows wird ja aufgerufen bevor das TreeView angezeigt wird und da rufe ich dann auch meine Suchfunktion auf. Und das scheint ja kein guter Zeitpunkt zu sein. Aber wenn mein TreeView angezeigt wird, ist es schon zu spät nach den Ordnern zu suchen und zu filtern.
Ich hab es nun mit einem QDirModel statt eines QFileSystemModels probiert. Da funtkioniert das mit dem rowCount ja an der Stelle.
Aber das QFileSystemModel scheint ja schneller zu sein als das QDirModell.
Wenn ich das QDirModell verwende muss der Anwender ewig warten, bevor ihm das Fenster mit dem TreeView angezeigt wird.
Also möchte ich doch wieder auf QFileSystemModel umsteigen.
Aber wann muss ich denn dann meine Funktion aufrufen, damit rowCount nicht 0 anzeigt?
Ich bin ratlos.
Hast das schon mal ohne ein Proxymodel mit den Filterfunktionen von QFileSystemModel versucht. Ich selber habe noch nicht mit QFileSystemModel gearbeitet. aber man kann dort Filter vorgeben.
Code: Alles auswählen
void setFilter ( Filters filters )
void setNameFilters ( const QStringList & nameFilters )