tutorial examples example ejemplo creator code qt model-view-controller qsortfilterproxymodel

examples - qt documentation



Uso de QSortFilterProxyModel con un modelo de árbol (4)

Tengo un QDirModel cuyo directorio actual está configurado. Luego tengo un QListView que se supone que muestra los archivos en ese directorio. Esto funciona bien

Ahora quiero limitar los archivos que se muestran, por lo que solo muestra los archivos png (el nombre del archivo termina con .png). El problema es que el uso de un QSortFilterProxyModel y la configuración del filtro de QSortFilterProxyModel también intentará hacer coincidir todos los padres de los archivos. De acuerdo con la documentación:

Para los modelos jerárquicos, el filtro se aplica recursivamente a todos los niños. Si un elemento principal no coincide con el filtro, no se mostrará ninguno de sus elementos secundarios.

Entonces, ¿cómo obtengo que QSortFilterProxyModel solo filtre los archivos en el directorio y no los directorios en los que reside?


Para personas como yo que están interesadas en el siguiente comportamiento: si un niño coincide con el filtro, sus antepasados ​​no deberían estar ocultos:

bool MySortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const { // custom behaviour : if(filterRegExp().isEmpty()==false) { // get source-model index for current row QModelIndex source_index = sourceModel()->index(source_row, this->filterKeyColumn(), source_parent) ; if(source_index.isValid()) { // if any of children matches the filter, then current index matches the filter as well int i, nb = sourceModel()->rowCount(source_index) ; for(i=0; i<nb; ++i) { if(filterAcceptsRow(i, source_index)) { return true ; } } // check current index itself : QString key = sourceModel()->data(source_index, filterRole()).toString(); return key.contains(filterRegExp()) ; } } // parent call for initial behaviour return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) ; }


Nos topamos con algo similar donde trabajo, y terminamos haciendo nuestro propio modelo proxy para hacer nuestro filtrado. Sin embargo, al buscar en la documentación lo que desea (que parece ser un caso más común), encontré dos posibilidades.

  1. Es posible que pueda establecer un filtro de nombre en QDirModel y filtrar las cosas de esa manera. No tengo idea si esto funcionará como usted desea, o si los filtros de nombre también se aplican a los directorios. La documentación es escasa en estos.
  2. Subclase el QSortFilterProxyModel y anule la función filterAcceptsRow . De la documentación:

El comportamiento de filtrado personalizado se puede lograr mediante la reimplementación de las funciones filterAcceptsRow () y filterAcceptsColumn ().

Entonces, presumiblemente, podría usar el índice del modelo para verificar si el elemento del índice es un directorio (se acepta automáticamente) o un archivo (filtro sobre el nombre del archivo).


derivar qsortfilterproxymodel y luego ...

bool YourQSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const { if (source_parent == qobject_cast<QStandardItemModel*>(sourceModel())->invisibleRootItem()->index()) { // always accept children of rootitem, since we want to filter their children return true; } return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); }