Search code examples
pythonpysideqtreeviewqfilesystemmodel

PySide: QFileSystemModel - Display/Show Root Item


i am using QFileSystemModel to display subdirectories of a set root path in a QTreeView. Works all fine but it would be very nice to also see the Root item as it is hidden right now.

model = QtGui.QFileSystemModel()
model.setRootPath(path)

treeview.setModel(model)
treeview.setRootIndex(model.index(path))
treeview.show()

EDIT: OS is Windows 7


Solution

  • The idea is to use as root the parent directory and filter the sibling directories, for this I created a QSortFilterProxyModel that receives an index from the desired directory but you must pass it a QPersistentModelIndex since the latter is permanent unlike the QModelIndex that can be changed in any moment.

    import os
    from PySide import QtCore, QtGui
    
    class FileProxyModel(QtGui.QSortFilterProxyModel):
        def setIndexPath(self, index):
            self._index_path = index
            self.invalidateFilter()
    
        def filterAcceptsRow(self, sourceRow, sourceParent):
            if hasattr(self, "_index_path"):
                ix = self.sourceModel().index(sourceRow, 0, sourceParent)
                if self._index_path.parent() == sourceParent and self._index_path != ix:
                    return False
            return super(FileProxyModel, self).filterAcceptsRow(sourceRow, sourceParent)
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        path = # ...
        parent_dir = os.path.abspath(os.path.join(path, os.pardir))
        treeview = QtGui.QTreeView()
        model = QtGui.QFileSystemModel(treeview)
        model.setRootPath(QtCore.QDir.rootPath())
        proxy = FileProxyModel(treeview)
        proxy.setSourceModel(model)
        proxy.setIndexPath(QtCore.QPersistentModelIndex(model.index(path)))
        treeview.setModel(proxy)
        treeview.setRootIndex(proxy.mapFromSource(model.index(parent_dir)))
        treeview.expandAll()
        treeview.show()
        sys.exit(app.exec_())