Using QFileSystemModel with ListView

本秂侑毒 提交于 2021-02-07 19:04:58

问题


I'm trying to create a simple ListView that I can use to browse the file system, using QFileSystem.

First, I tried to use code I've found that worked for QDirModel:

main.qml:

    ListView {
        id: list
        width: 300
        height: 500

        model: DelegateModel {
            model: myFileModel

            delegate: Text{
                id: txt
                text: fileName

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        //Switch directory when clicked
                        list.model.rootIndex = list.model.modelIndex(index);
                    }

                }
            }
        }

main.cpp:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;


    QFileSystemModel qdm;
    qdm.setFilter( QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files );

    qdm.setRootPath("/");
    engine.rootContext()->setContextProperty("myFileModel", &qdm);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

However, this code resets the ListView every time the QFileSystemModel loads another piece of the filesystem. Video here - you can see how clicking on a new folder for the first time resets the view to the model's root. At the second attempt, you can also see that the correct folder's contents are shown for a fraction of a second before the view is reset.

My thinking was that, since QFileSystemModel loads its data asynchronously, maybe the model index is invalidated once the model is updated, thus resetting the views. So I tried to re-assign the rootIndex every time the model's directoryLoaded signal is emitted.

main.qml:

ListView {
        id: list
        width: 300
        height: 500

        model: DelegateModel {
            model: myFileModel

            property var ind: myModelIndex

            onIndChanged: {
                rootIndex = myModelIndex //manually reassign root
            }

            delegate: Text{
                id: txt
                text: fileName

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        list.model.rootIndex = list.model.modelIndex(index);
                    }

                }
            }
        }

main.cpp:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    QFileSystemModel qdm;
    qdm.setFilter( QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files );

    QObject::connect(&qdm, &QFileSystemModel::directoryLoaded, [&](const QString& path){
        //Update model index after directory completely loaded
        engine.rootContext()->setContextProperty("myModelIndex", qdm.index(path));
    });

    qdm.setRootPath("/");
    engine.rootContext()->setContextProperty("myModelIndex", qdm.index(""));
    engine.rootContext()->setContextProperty("myFileModel", &qdm);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

However, the outcome is the exact same. I've added debugging code and it seems the model properly loads all new directory data, then the view's rootIndex is changed. Still, however, the view is reset every time.

To add to that, I've also set up a separate TreeView that also uses myFileModel and model as myRootIndex as root index. And that one works perfectly. It's just ListView (and GridView as well) that don't work.

There is virtually no info on using QFileSystemModel with anything other than TreeView, as far as I can see. I'd love some input on what is happening.

来源:https://stackoverflow.com/questions/38169880/using-qfilesystemmodel-with-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!