3

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_())
NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
JokerMartini
  • 5,674
  • 9
  • 83
  • 193

3 Answers3

1

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
Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
1

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
mrprfrm
  • 106
  • 1
  • 4
1

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

Community
  • 1
  • 1
Softmixt
  • 1,658
  • 20
  • 20