Search code examples
qtqtreeview

QTreeView show only parent directory, rather than parent and all its siblings


I'm trying to get QTreeView (using an underlying QFileSystemModel) to show a directory tree. If I set the RootPath to the parent directory, then I see all the children, but not the parent. If I set the RootPath to be the parent's parent, then I see the parent directory with all its siblings. Is there a way to get it to show the parent without its siblings, and all the children?

Thanks


Solution

  • This works for me on Linux. I'm not claiming it's the best implementation and I'm not sure if using backslash separators will work on Windows. I know Qt translates them to the native separator but I don't know if it's native separators that come out of the model's data method.

    #include <QApplication>
    #include <QFileSystemModel>
    #include <QSortFilterProxyModel>
    #include <QTreeView>
    
    class FilterModel : public QSortFilterProxyModel
    {
    public:
        FilterModel( const QString& targetDir ) : dir( targetDir )
        {
            if ( !dir.endsWith( "/" ) )
            {
                dir += "/";
            }
        }
    
    protected:
        virtual bool filterAcceptsRow( int source_row
                                     , const QModelIndex & source_parent ) const
        {
            QString path;
            QModelIndex pathIndex = source_parent.child( source_row, 0 );
            while ( pathIndex.parent().isValid() )
            {
                path = sourceModel()->data( pathIndex ).toString() + "/" + path;
                pathIndex = pathIndex.parent();
            }
            // Get the leading "/" on Linux. Drive on Windows?
            path = sourceModel()->data( pathIndex ).toString() + path;
    
            // First test matches paths before we've reached the target directory.
            // Second test matches paths after we've passed the target directory.
            return dir.startsWith( path ) || path.startsWith( dir );
        }
    
    private:
        QString dir;
    };
    
    int main( int argc, char** argv )
    {
        QApplication app( argc, argv );
    
        const QString dir( "/home" );
        const QString targetDir( dir + "/sample"  );
    
        QFileSystemModel*const model = new QFileSystemModel;
        model->setRootPath( targetDir );
    
        FilterModel*const filter = new FilterModel( targetDir );
        filter->setSourceModel( model );
    
        QTreeView*const tree = new QTreeView();
        tree->setModel( filter );
        tree->setRootIndex( filter->mapFromSource( model->index( dir ) ) );
        tree->show();
    
        return app.exec();
    }