Search code examples
pythonqtreeviewpyside2qfilesystemmodel

How to correct the "expand/collapse" icon on the QTreeView?


enter image description here

when you see this expand icon, you will think that there are something under the folder. but there is nothing. this issue causes a poor user experience. how to fix it? (** if the folder is empty, the expand icon is not displayed.)

my code basically looks like this:

QFileSystemModel ---> QTreeView

edit3:

import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *

libPath = 'f:/tmp22'

# RUN ------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)

    # data model ----------------------------------------------------------
    treeModel = QFileSystemModel()
    treeModel.setFilter(QDir.NoDotAndDotDot | QDir.Dirs)
    treeModel.setRootPath(libPath)

    # setup ui -------------------------------------------------------------
    treeView = QTreeView()
    treeView.setModel(treeModel)
    treeView.setRootIndex(treeModel.index(libPath))

    # show ui -------------------------------------------------------------
    treeView.show()
    sys.exit(app.exec_())

the structure of the folders:

F:/tmp22
F:/tmp22/folder1    <-------- empty!
F:/tmp22/_folder2   <-------- empty!

Solution

  • It seems that QFileSystemModel considers that a folder will always have children so that hasChildren() returns True in that case. To correct this problem, this method must be overridden by returning false if the folder does not comply with the filter.

    import sys
    
    # PySide2
    from PySide2.QtCore import QDir, QSortFilterProxyModel
    from PySide2.QtWidgets import QApplication, QFileSystemModel, QTreeView
    
    
    libPath = 'f:/tmp22'
    
    
    class FileSystemModel(QFileSystemModel):
        def hasChildren(self, parent):
            file_info = self.fileInfo(parent)
            _dir = QDir(file_info.absoluteFilePath())
            return bool(_dir.entryList(self.filter()))
    
    # RUN ------------------------------------------------------------------
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        # data model ----------------------------------------------------------
        treeModel = FileSystemModel()
        treeModel.setFilter(QDir.NoDotAndDotDot | QDir.Dirs)
        treeModel.setRootPath(libPath)
    
        # setup ui -------------------------------------------------------------
        treeView = QTreeView()
        treeView.setModel(treeModel)
        treeView.setRootIndex(treeModel.index(libPath))
    
        # show ui -------------------------------------------------------------
        treeView.show()
        sys.exit(app.exec_())