JokerMartini
JokerMartini

Reputation: 6147

Display folders/files with different icons in QTreeView

I have written a function in Python which goes through a specified directory and gets all its files and sub-folders recursively and filtering it to only list certain file formats. How do I display this in a treeview with an different icon for folders vs files?

recursive directory function:

def test(self):
    formats = ['.jpg', '.jpeg', '.txt']

    for path, subdirs, files in os.walk(r'C:/Users/jmartini/Projects/Photogrammetry'):
        for file in files:
            filename, extension = os.path.splitext(file)

            if (extension.lower() in formats):
                f = os.path.join(path, file)
                print f

Concept

enter image description here

Entire application code:

import sys
import os
from PySide import QtGui, QtCore


class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):      
        # formatting
        self.resize(550, 400)
        self.setWindowTitle("Toychest")

        # widgets
        self.toollist = QtGui.QTreeView()

        # Tabs

        # signals

        # main layout
        mainLayout = QtGui.QGridLayout()
        mainLayout.setContentsMargins(0,0,0,0)
        mainLayout.addWidget(self.toollist)
        self.setLayout(mainLayout)

        # self.test()

# Functions
# ------------------------------------------------------------------------------
    def test(self):
        formats = ['.jpg', '.jpeg', '.txt']

        for path, subdirs, files in os.walk(r'C:/Users/jmartini/Projects/Photogrammetry'):
            for file in files:
                filename, extension = os.path.splitext(file)

                if (extension.lower() in formats):
                    f = os.path.join(path, file)
                    print f


# Main
# ------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

Upvotes: 3

Views: 4765

Answers (3)

Softmixt
Softmixt

Reputation: 1756

You can check here a PyQT5 function to list directory structure using QTreeWidgetItem

Upvotes: 1

mrprfrm
mrprfrm

Reputation: 106

Try to use QStandardItemModel and QStandardItem when you build directory tree.

Use setIcon method of QStandardItem

For example:

import os
import PyQt4.QtGui

class Example(QtGui.QWidget):
    DEFAULT_DIR_PATH = 'C:/Users/jmartini/Projects/Photogrammetry'
    DIR_ICON_PATH = 'dir/icon/path/dir.jpg'
    FILE_ICON_PATH = 'file/icon/path/file.jpg'

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()
        self.initDirectory(DEFAULT_DIR_PATH)

    def initUI(self):      
        # formatting
        self.resize(550, 400)
        self.setWindowTitle("Toychest")

        # widgets
        self.toollist = QtGui.QTreeView()

        # QTreeView use QStandardItemModel as data source
        self.source_model = QtGui.QStandardItemModel()

        # Tabs

        # signals

        # main layout
        mainLayout = QtGui.QGridLayout()
        mainLayout.setContentsMargins(0,0,0,0)
        mainLayout.addWidget(self.toollist)
        self.setLayout(mainLayout)
        # set model for toollist
        self.toollist.setModel(self.source_model)

    def initDirectory(self, path):
        new_item = newItem(path)
        self.readDirectory(path, new_item)
        self.source_model.appendRow(new_item)

    def readDirectory(self, path, parent_item):
        directory = os.listdir(path)
        for file_name in directory:
            file_path = path + '/' + file_name
            new_item = newItem(file_path)
            parent_item.appendRow(new_item)
            if os.path.isdir(file_path):
                self.readDirectory(file_path, new_item)

    def newItem(self, path):
        title = os.path.basename(path)
        item = QtGui.QStandardItem()
        icon_path = FILE_ICON_PATH
        if os.path.isdir(file_path):
            icon_path = DIR_ICON_PATH
        icon = QtGui.QIcon(icon_path)
        item.setText(title)
        item.setIcon(icon)
        return item

Upvotes: 1

Brendan Abel
Brendan Abel

Reputation: 37509

When adding a new item to the tree, it first has to find the item in the tree that it should be parented to. For example

path = '/path/to/file.jpg'

To create this item in the tree, I first need to find the top-level item for path. Then, I need to find a child of that item for to. Then, I can add the file.jpg item.

def find_or_create_item(self, path, parent=None):
    if parent is None:
        parent = self.tree.invisibleRootItem()
    names = path.lstrip('/').split('/')
    name = names[0]
    for i in range(parent.childCount()):
        child = parent.child(i)
        if child.text(0) == name:
            item = child
            break
    else:
        item = QTreeWidgetItem(name)
        parent.addChild(item)

    if names[1:]:
        return self.find_or_create_item('/'.join(names[1:], item)
    else:
        return item

Upvotes: 1

Related Questions