完全展开代表QFileSystemModel的QTreeView

1 投票
2 回答
2633 浏览
提问于 2025-04-18 14:30

我正在使用QTreeView来显示一个目录的内容。它的功能正常,但我希望能把所有的层级都展开来显示。我原以为使用QTreeView.expandAll()这个方法就能做到,但实际上在展开根目录之前,子目录的ModelItems似乎并不存在。为了能完全展开我的目录结构,我需要做些什么呢?

import sys
from PyQt4 import QtGui

class Example(QtGui.QWidget):

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

    self.initUI()

    def initUI(self):
        self.treeView = QtGui.QTreeView(self)
        self.treeView.setGeometry(0,0, 600, 800)
        self.model = QtGui.QFileSystemModel()
        self.path = "/opt"
        self.model.setRootPath(self.path)
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.model.index(self.path))
        self.treeView.expandAll()

        self.setGeometry(300, 300, 600, 800)
        self.setWindowTitle('Toggle button')
        self.show()

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

我通过使用os.walk来遍历目录,并手动设置根路径,得到了想要的结果,如下所示。不过,我在想是否有更“内置”的Qt方法可以实现这个功能。

    for root, dirs, files in os.walk(self.path):
        self.model.setRootPath(root)

2 个回答

0

我找到了解决办法:

    if choice != 1:
        self.model.directoryLoaded.connect(self.expand)
    else:
        pass
        
    
def expand(self):
    self.emp.treeViewFolderView.expandAll()

directoryLoaded就是解决问题的关键!

2

首先,你确定真的想这么做吗?QFileSystemModel 之所以采用懒加载的方式,是有原因的。一次性查询整个目录树可能会很耗费资源和时间。

如果你想用更符合 Qt 的方式,可以使用 directoryLoaded 信号,来在子文件夹加载时获取并展开它们:

class Example(QtGui.QWidget):

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

    self.initUI()

    def initUI(self):
        self.treeView = QtGui.QTreeView(self)
        self.treeView.setGeometry(0,0, 600, 800)
        self.model = QtGui.QFileSystemModel()
        self.path = "/opt"
        self.model.setRootPath(self.path)
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.model.index(self.path))
        # self.treeView.expandAll()  Not needed

        self.setGeometry(300, 300, 600, 800)
        self.setWindowTitle('Toggle button')

        self.model.directoryLoaded.connect(self._fetchAndExpand)

        self.show()

    def _fetchAndExpand(self, path):
        index = self.model.index(path)
        self.treeView.expand(index)  # expand the item
        for i in range(self.model.rowCount(index)):
            # fetch all the sub-folders
            child = index.child(i, 0)
            if self.model.isDir(child):
                self.model.setRootPath(self.model.filePath(child))

注意:对于一个很大的目录树,这可能会让界面在一段时间内卡住。这并不是因为模型本身,而是因为视图在处理每个展开的项目时需要做很多工作,这些工作加起来就会导致延迟。

撰写回答