2008-10-30 9 views
7

Tengo un QDirModel cuyo directorio actual está configurado. Luego tengo un QListView que se supone que muestra los archivos en ese directorio. Esto funciona bienUso de QSortFilterProxyModel con un modelo de árbol

Ahora quiero limitar los archivos que se muestran, por lo que solo se muestran png archivos (el nombre del archivo termina en .png). El problema es que usando un QSortFilterProxyModel y configurando el filtro de expresiones regulares, intentará hacer coincidir todos los padres de los archivos también. Según la documentación:

Para los modelos jerárquicos, el filtro es aplicado 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 el QSortFilterProxyModel para filtrar solo los archivos en el directorio y no en los directorios en los que reside?

Respuesta

7

Nos encontramos con algo similar donde trabajo, y terminamos haciendo nuestro propio modelo de 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 el QDirModel y filtrar las cosas de esa manera. No tengo idea de 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 QSortFilterProxyModel y anula la función filterAcceptsRow. A partir de la documentación:

personalizada comportamiento de filtrado se puede lograr mediante la reimplementar() funciones filterAcceptsRow() y filterAcceptsColumn.

Luego, presumiblemente puede usar el índice del modelo para verificar si el elemento del índice es un directorio (aceptar automáticamente) o un archivo (filtro sobre el nombre del archivo).

1

derivan 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); 
} 
6

Para gente como yo que están interesados ​​en el comportamiento siguiente: si un niño coincide con el filtro, a continuación, sus antepasados ​​no deben ser escondidos:

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) ; 
} 
Cuestiones relacionadas