我的QFileSystemModel在PyQt中表现不如预期

2 投票
2 回答
2547 浏览
提问于 2025-04-15 21:43

编辑2:调用 model.hasChildren(parentIndex) 返回 True,但是 model.rowCount(parentIndex) 返回 0。难道 QFileSystemModel 在 PyQt 中有问题吗?

编辑:经过一些调整,如果我使用 QDirModel,这一切都能正常工作。虽然 QDirModel 已经不推荐使用了,但也许 QFileSystemModel 在 PyQt 中还没有完全实现?


我现在正在学习 Qt 的模型/视图架构,发现了一些和我预期不一样的情况。我有以下代码(改编自 Qt 模型类):

from PyQt4 import QtCore, QtGui

model = QtGui.QFileSystemModel()

parentIndex = model.index(QtCore.QDir.currentPath())
print model.isDir(parentIndex) #prints True
print model.data(parentIndex).toString() #prints name of current directory

rows = model.rowCount(parentIndex)
print rows #prints 0 (even though the current directory has directory and file children)

问题:

这是 PyQt 的问题吗?我是不是做错了什么,还是我完全误解了 QFileSystemModel?根据文档,model.rowCount(parentIndex) 应该返回当前目录中的子项数量。(我在 Ubuntu 上运行这个,使用的是 Python 2.6)

QFileSystemModel 的文档说它需要一个图形应用程序的实例,所以我也把上面的代码放在一个 QWidget 中,如下所示,但结果还是一样:

import sys
from PyQt4 import QtCore, QtGui

class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        model = QtGui.QFileSystemModel()

        parentIndex = model.index(QtCore.QDir.currentPath())
        print model.isDir(parentIndex)
        print model.data(parentIndex).toString()

        rows = model.rowCount(parentIndex)
        print rows


def main():
    app = QtGui.QApplication(sys.argv)
    widget = Widget()
    widget.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

2 个回答

1

既然你已经搞明白了,我再补充几点关于你模型的想法:QFileSystemModel::rowCount这个函数返回的是可见子项的行数;我想你已经正确识别了问题:在你检查行数的时候,它还没有被填充好。我把你的例子改了一下,没有使用定时器;请检查一下这样是否对你有效:

class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.model = QtGui.QFileSystemModel()
        self.model.setRootPath(QtCore.QDir.currentPath())

    def checkParent(self):
        parentIndex = self.model.index(QtCore.QDir.currentPath())      

        print self.model.isDir(parentIndex)
        print self.model.data(parentIndex).toString()

        rows = self.model.rowCount(parentIndex)
        print "row count:", rows

def main():
    app = QtGui.QApplication(sys.argv)
    widget = Widget()
    widget.show()
    app.processEvents(QtCore.QEventLoop.AllEvents)  
    widget.checkParent()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

我相信你的代码在任何用户界面事件发生后,只要这个小部件已经显示在屏幕上,就应该能正常工作。

祝好

2

我解决了这个问题。

使用QFileSystemModel而不是QDirModel的原因是,QFileSystemModel会在一个单独的线程中从文件系统加载数据。这样做的问题是,如果你在它刚创建好后就去打印子项的数量,可能会发现子项还没有加载完成。要解决上面的代码问题,可以在构造函数的最后添加以下内容:

self.timer = QtCore.QTimer(self)
self.timer.singleShot(1, self.printRowCount)

并且添加一个printRowCount方法,这样就能正确打印出子项的数量了。呼,终于解决了。

撰写回答