pythonpython-3.xqtreeviewpyqt6qstandarditemmodel

In Python PyQt6, Why is my QTreeView displaying white icons instead of folder icons from QStandardItemModel?


I am attempting to add a folder icon for the folder items in my directory, along with the icons for the associated file type.

iconProvider = QFileIconProvider()

        for item in os.listdir(path):
            QItem = QStandardItem(item)
            file_item_icon = iconProvider.icon(QFileInfo(item))
            QItem.setIcon(file_item_icon)
            root_item.appendRow(QItem)

QTreeView Where folders show up with a White Icon

QTreeView Where folders show up with a White Icon

I have tried using the QFileSystemModel which does correctly show the icons, However, I need the control the QStandardItemModel offers...

QTreeView where icons are working

QTreeView where icons are working


Solution

  • If the path used to construct the QFileInfo instance is not absolute, it can only use relative paths. As the documentation explains:

    A QFileInfo can point to a file with either a relative or an absolute file path. Absolute file paths begin with the directory separator "/" (or with a drive specification on Windows). Relative file names begin with a directory name or a file name and specify a path relative to the current working directory.

    [emphasis mine]

    os.listdir() returns only the names:

    Return a list containing the names of the entries in the directory given by path.

    This means that QFileInfo will only have a "relative" name of each entry based on the working directory.

    This is clearly an issue in your case:

    So, the solution is to use absolute paths or the proper icon type.

    For simple cases (when the icon type is known), you can use the icon(IconType) override using the provided enum. For instance, if you do know that the path refers to a directory (i.e. os.path.isdir()):

    file_item_icon = iconProvider.icon(iconProvider.IconType.Folder)
    

    Otherwise, you should use the full path, so that QFileInfo will use the real file reference:

    baseDir = QDir(path)
    for fileName in os.listdir(path):
        info = QFileInfo(baseDir.absoluteFilePath(fileName))
        icon = iconProvider.icon(info)
        root_item.appendRow(QStandardItem(icon, fileName))