Почему мой QFileSystemModel QModelIndex не может получить информацию о дочернем узле? - PullRequest
1 голос
/ 08 ноября 2019

Я узнал об архитектуре Модель / Представление в pyqt, но когда я следую инструкции Использование модельных индексов и пытаюсь написать демонстрацию в стиле pyqt5. QModelIndex не может получить информацию о дочернем узле?

Код:

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

Результат:

Моя папка:

1 Ответ

1 голос
/ 08 ноября 2019

Объяснение:

Как указывают документы ( 1 , 2 ):

Кэширование и производительность

QFileSystemModel не будет загружать какие-либо файлы или каталоги, пока не будет вызвана setRootPath (). Это предотвратит любые ненужные запросы в файловой системе до этой точки, например, список дисков в Windows.

В отличие от QDirModel, QFileSystemModel использует отдельный поток для заполнения себя, поэтому он не приведет к зависанию основного потока в качествеФайловая система запрашивается. Вызовы rowCount () будут возвращать 0, пока модель не заполнит каталог.

QFileSystemModel хранит кэш с информацией о файле. Кэш автоматически обновляется с использованием QFileSystemWatcher.


QModelIndex QFileSystemModel :: setRootPath (const QString & newPath)

Устанавливает каталог, который отслеживаетсяпо модели в newPath, установив на нее наблюдателя файловой системы. Любые изменения в файлах и каталогах в этом каталоге будут отражены в модели.

Если путь будет изменен, будет выдан сигнал rootPathChanged ().

Примечание: эта функцияне меняет структуру модели и не изменяет данные, доступные для просмотра. Другими словами, «корень» модели не изменяется, чтобы включать в себя только файлы и каталоги в каталоге, указанном newPath в файловой системе.

выделение шахты

Процесс загрузки выполняется в другом потоке, а загрузка выполняется асинхронно, поэтому во время выполнения запроса модель еще не загружена.

Решение:

Решение состоит в том, чтобы запросить информацию после ее загрузки, которая будет уведомлена через сигнал directoryLoaded 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_())
...