首页 > 解决方案 > 带有 QFileSystemModel 的 QTreeView 无法正常工作

问题描述

我设置 QFileSystemModel 根路径,然后将其设置为 QTreeView 模型,但是如果我尝试查找特定文件的索引,它会给我 D:我确定文件在那里!

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

标签: pythonpyqtpyqt5qtreeviewqfilesystemmodel

解决方案


如果审查了文档:

QModelIndex QFileSystemModel::setRootPath(const QString &newPath)

通过在其上安装文件系统观察程序,将模型正在监视的目录设置为 newPath。对该目录中文件和目录的任何更改都将反映在模型中。

如果路径改变,将发出 rootPathChanged() 信号。

注意:此功能不会更改模型的结构或修改视图可用的数据。换句话说,模型的“根”没有更改为仅包括文件系统中由 newPath 指定的目录中的文件和目录。

(强调我的)

据了解,模型的根从未改变,因此如果您想访问 rootPath 下的项目,您必须获取与该路径关联的 QModelIndex ,然后获取您的孩子。

另一方面,QFileSystemModel 在另一个线程中执行其任务以避免某些 GUI 阻塞,因此在更改 rootPath 时您将无法获得足够的路由,但至少您必须等待发出指示工作的 directoryLoaded 信号线程上做完了。

考虑到上述情况,一个可能的解决方案是:

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_())

推荐阅读