Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
878 views
in Technique[技术] by (71.8m points)

python - Why my QFileSystemModel QModelIndex couldn't get child node infomation?

I am learn about Model/View architecture in pyqt, but when i follow the Using model indexes instruction and try to write a demo in pyqt5 style.The QModelIndex couldn't get child node information?

The code:

class DemoB(QPushButton):
    def __init__(self):
        super().__init__()

        self.clicked.connect(self.on_clicked)

    def on_clicked(self, checked):
        model = QFileSystemModel()
        model.setRootPath(QDir.homePath())
        parentIndex = model.index(QDir.homePath())
        print(parentIndex.data() )
        print(parentIndex, model.rowCount(parentIndex), QDir.homePath())
        for row in range(model.rowCount(parentIndex)):
            index = model.index(row, 0, parentIndex)
            print(index, index.data())

The result:

My folder:

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Explanation:

As the docs(1, 2) points out:

Caching and Performance

QFileSystemModel will not fetch any files or directories until setRootPath() is called. This will prevent any unnecessary querying on the file system until that point such as listing the drives on Windows.

Unlike QDirModel, QFileSystemModel uses a separate thread to populate itself so it will not cause the main thread to hang as the file system is being queried. Calls to rowCount() will return 0 until the model populates a directory.

QFileSystemModel keeps a cache with file information. The cache is automatically kept up to date using the QFileSystemWatcher.


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

The loading process is executed in a different thread and the loading is done asynchronously, so at the time you make the request the model is not yet loaded.

Solution:

The solution is to request the information after it has been loaded that will be notified through the directoryLoaded signal of QFileSystemModel:

from PyQt5.QtCore import pyqtSlot, QDir
from PyQt5.QtWidgets import QApplication, QFileSystemModel, QPushButton


class DemoB(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.clicked.connect(self.on_clicked)
        self.model = QFileSystemModel(self)
        self.model.directoryLoaded.connect(self.on_directoryLoaded)

    @pyqtSlot()
    def on_clicked(self):
        self.model.setRootPath(QDir.homePath())

    @pyqtSlot(str)
    def on_directoryLoaded(self, directory):
        parentIndex = self.model.index(directory)
        for row in range(self.model.rowCount(parentIndex)):
            index = self.model.index(row, 0, parentIndex)
            print(index, index.data())


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = DemoB()
    w.show()
    sys.exit(app.exec_())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...