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.
- 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.
- 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);
}
Solo use el modelo KRecursiveFilterProxyModel de KItemModels KDE API