QTreeView with QFileSystemModel is not working properly
Asked Answered
C

1

2

I set QFileSystemModel root path and then set it as QTreeView model, but if I try to find index of a speciffic file it is giving me D: I am sure the file is there !

self.model = QtWidgets.QFileSystemModel()
self.model.setNameFilters(['*.ma'])
self.model.setFilter(QtCore.QDir.Files)#QtCore.QDir.AllDirs | QtCore.QDir.NoDotAndDotDot | QtCore.QDir.AllEntries)
self.model.setNameFilterDisables(False)
self.model.setRootPath(path)
self.tree_local_file.setModel(self.model)
self.tree_local_file.setRootIndex(self.model.index(path))

# ...
# then
# ...

for i in range(self.model.rowCount()):
    index = self.model.index(i, 0)
    file_name = str(self.model.fileName(index))
    file_path = str(self.model.filePath(index))
    print(file_path) # this gave me -> D:/
    if file_name == master_file_name:
        self.tree_local_file.setCurrentIndex(index)
        self.open_file()
        break
# or

index = (self.model.index(master_file_name[1]))
print(self.model.filePath(index)) # this is giving me nothing
Coatbridge answered 25/7, 2019 at 3:9 Comment(0)
A
2

If the docs is reviewed:

QModelIndex QFileSystemModel::setRootPath(const QString &newPath)

Sets the directory that is being watched by the model to newPath by installing a file system watcher on it. Any changes to files and directories within this directory will be reflected in the model.

If the path is changed, the rootPathChanged() signal will be emitted.

Note: This function does not change the structure of the model or modify the data available to views. In other words, the "root" of the model is not changed to include only files and directories within the directory specified by newPath in the file system.

(emphasis mine)

From what is understood that the root of the model has never changed, so if you want to access the items below the rootPath you must obtain the QModelIndex associated with that path and then get your children.

On the other hand, QFileSystemModel performs its tasks in another thread to avoid some blocking of the GUI so you will not get an adequate route as you change the rootPath but at least you have to wait for the directoryLoaded signal to be issued indicating that the work done on the thread is over.

Considering the above a possible solution is:

from PyQt5 import QtCore, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.tree_local_file = QtWidgets.QTreeView()
        self.setCentralWidget(self.tree_local_file)

        path = "/foo/path/"

        self.model = QtWidgets.QFileSystemModel()
        self.model.setNameFilters(["*.ma"])
        self.model.setFilter(
            QtCore.QDir.Files
        )  # QtCore.QDir.AllDirs | QtCore.QDir.NoDotAndDotDot | QtCore.QDir.AllEntries)
        self.model.setNameFilterDisables(False)
        self.model.setRootPath(path)
        self.tree_local_file.setModel(self.model)
        self.tree_local_file.setRootIndex(self.model.index(path))

        self.model.directoryLoaded.connect(self.onDirectoryLoaded)

    @QtCore.pyqtSlot()
    def onDirectoryLoaded(self):
        root = self.model.index(self.model.rootPath())
        for i in range(self.model.rowCount(root)):
            index = self.model.index(i, 0, root)
            file_name = self.model.fileName(index)
            file_path = self.model.filePath(index)
            print(file_path)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
Alary answered 25/7, 2019 at 3:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.