当前位置:   article > 正文

qml 实现展示本地文件系统_qml实现系统

qml实现系统

遍历本地文件

qt 提供了很多种便利类来实现本地的文件系统管理,比如QDirModelQFileSystemModel,qml中又提供了FolderListModel 。需要包含Qt.labs.folderlistmodel 2.0
笔者的环境没有安装Qt.labs.folderlistmodel 2.0 所以只能在QDirModelQFileSystemModel来选择,缺点是pro 文件中要添加QT += widgets, 因为该模块实现需要依赖widgets。

对于 QDirModel和 QFileSystemModel的选择
在QDirModel文档中说明

此类已过时。它提供了保持旧的源代码工作。我们强烈建议不要在新代码中使用它。

所以最终选择了QFileSystemModel
QFileSystemModel 采用单独的线程获取目录文件结构,而 QDirModel 不使用单独的线程。使用单独的线程就不会阻碍主线程,所以推荐使用 QFileSystemModel

核心代码

本文章代码参考了git上一个demo,但是添加了一些代码,主要是可以返回上一级
参考代码的git地址 : https://github.com/junyius1/filesystembrowser

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QFileSystemModel>
#include <QDateTime>
#include <QDesktopServices>
#include <QUrl>
#include <QDirModel>
#include <QQuickView>

static inline QString permissionString(const QFileInfo &fi)
{
    const QFile::Permissions permissions = fi.permissions();
    QString result = QLatin1String("----------");
    if (fi.isSymLink())
        result[0] = QLatin1Char('l');
    else if (fi.isDir())
        result[0] = QLatin1Char('d');
    if (permissions & QFileDevice::ReadUser)
        result[1] = QLatin1Char('r');
    if (permissions & QFileDevice::WriteUser)
        result[2] = QLatin1Char('w');
    if (permissions & QFileDevice::ExeUser)
        result[3] = QLatin1Char('x');
    if (permissions & QFileDevice::ReadGroup)
        result[4] = QLatin1Char('r');
    if (permissions & QFileDevice::WriteGroup)
        result[5] = QLatin1Char('w');
    if (permissions & QFileDevice::ExeGroup)
        result[6] = QLatin1Char('x');
    if (permissions & QFileDevice::ReadOther)
        result[7] = QLatin1Char('r');
    if (permissions & QFileDevice::WriteOther)
        result[8] = QLatin1Char('w');
    if (permissions & QFileDevice::ExeOther)
        result[9] = QLatin1Char('x');
    return result;
}

static inline QString sizeString(const QFileInfo &fi)
{
    if (!fi.isFile())
        return QString();
    const qint64 size = fi.size();
    if (size > 1024 * 1024 * 10)
        return QString::number(size / (1024 * 1024)) + QLatin1Char('M');
    if (size > 1024 * 10)
        return QString::number(size / 1024) + QLatin1Char('K');
    return QString::number(size);
}

class DisplayFileSystemModel : public QFileSystemModel {
    Q_OBJECT
public:
    explicit DisplayFileSystemModel(QObject *parent = nullptr)
        : QFileSystemModel(parent) {

    }

public Q_SLOTS:
    void onRootPathChanged(const QString &newPath)
    {
        qDebug()<< "=====" << "onRootPathChanged==="<<newPath;
    }
public:
    enum Roles  {
        SizeRole = Qt::UserRole + 4,
        DisplayableFilePermissionsRole = Qt::UserRole + 5,
        LastModifiedRole = Qt::UserRole + 6,
        UrlStringRole = Qt::UserRole + 7,
        //NameRole = Qt::UserRole + 8
    };
    Q_ENUM(Roles)

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    {
        if (index.isValid() && role >= SizeRole) {
            switch (role) {
            case SizeRole:
                return QVariant(sizeString(fileInfo(index)));
            case DisplayableFilePermissionsRole:
                return QVariant(permissionString(fileInfo(index)));
            case LastModifiedRole:
                return QVariant(fileInfo(index).lastModified().toString(Qt::SystemLocaleShortDate));
            case UrlStringRole:
                return QVariant(QUrl::fromLocalFile(filePath(index)).toString());
            default:
                break;
            }
        }
        return QFileSystemModel::data(index, role);
    }

    QHash<int,QByteArray> roleNames() const override
    {
         QHash<int, QByteArray> result = QFileSystemModel::roleNames();
         result.insert(SizeRole, QByteArrayLiteral("size"));
         result.insert(DisplayableFilePermissionsRole, QByteArrayLiteral("displayableFilePermissions"));
         result.insert(LastModifiedRole, QByteArrayLiteral("lastModified"));
         //result.insert(NameRole,QByteArrayLiteral("name"));
         return result;
    }

public:
    Q_INVOKABLE bool _isDir(const QModelIndex &index)
    {
        return isDir(index);
    }

    Q_INVOKABLE QModelIndex  parentIndex(const QModelIndex &index)
    {
        return parent(index);
    }
};


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

    QQuickView view;
    QFileSystemModel *fsm = new DisplayFileSystemModel(&view);
//    QFileSystemModel *fsm = new QFileSystemModel(&view);
     QObject::connect(fsm, SIGNAL(rootPathChanged(const QString)), fsm,
            SLOT(onRootPathChanged(const QString)));
    QModelIndex lIndex = fsm->setRootPath(QDir::homePath());
//    fsm->setResolveSymlinks(true);
    view.rootContext()->setContextProperty("rootPathIndex", lIndex);
    view.rootContext()->setContextProperty("fileSystemModel", fsm);
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();

    return app.exec();
}

#include "main.moc"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136

main.qml

import QtQuick 2.2
import QtQml.Models 2.2
import QtQuick.Controls 2.3


Rectangle
{
    id:root
    width: 500
    height: 800

    Button
    {
        id:back
        y:460
        z:100
        text: "back"
        onClicked:
        {
            console.log("back clicked")
            view.setParentModel();
        }
    }

    ListView {
        id: view
        width: 300
        height: 400


        function getParentModel()
        {
           return view.model.parentIndex
        }

        function setParentModel()
        {
            console.log(view.model.indexArray.length)
            if(view.model.indexArray.length === 1)
                return
            view.model.indexArray.pop();

            view.model.testIndex= fileSystemModel.parentIndex(view.model.rootIndex)
            view.model.rootIndex = view.model.testIndex
           console.log(view.model.indexArray.length,view.model.indexArray)
            
            //方法2
//            view.model.testIndex= view.model.indexArray[viewmodel.indexArray.length-1]
//            viewmodel.rootIndex = viewmodel.indexArray[viewmodel.indexArray.length-1]
//            view.model.rootIndex = view.model.testIndex
        }

        model: DelegateModel {
            property var testIndex
            property var parentIndex
            property var indexArray: new Array;  //方法2

            model: fileSystemModel
            rootIndex:{
                view.model.testIndex = rootPathIndex
                //方法2
                view.model.indexArray.push(rootPathIndex);
                console.log("set rootIndex==",view.model.indexArray.length ,view.model.testIndex)
                //return rootPathIndex
            }
            onRootIndexChanged:{
                view.model.rootIndex = view.model.testIndex
                 console.log("set onRootIndexChanged==",view.model.testIndex)
            }

            delegate: Rectangle {

                width: 200; height: 65


                Image{
                    id:img
                    source:fileSystemModel._isDir(view.model.modelIndex(index))? "qrc:/dir.png":"qrc:/listenItem.png"
                }

                Text{
                    text: fileName
                    anchors.verticalCenter: img.verticalCenter
                    anchors.left: img.right
                    anchors.leftMargin: 10
                }

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        if (model.hasModelChildren){
                            console.log("clicked",view.model.testIndex);

                            view.model.testIndex= view.model.modelIndex(index)
                            view.model.rootIndex = view.model.modelIndex(index)
                            //方法2
                            view.model.indexArray.push(view.model.testIndex);
                            console.log("clikced ", view.model.indexArray.length)
                        }
                    }
                }
            }
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

上述代码实现了两种方法来返回上一层,最早是使用了一个array来记录各层级节点,
后来找到了获得父节点的方法,所以用了最新获得父节点的方式来实现。代码中有些还是不太明白,等有时间了再自信琢磨琢磨。
尤其是:

onRootIndexChanged:{
                view.model.rootIndex = view.model.testIndex
                 console.log("set onRootIndexChanged==",view.model.testIndex)
            }
  • 1
  • 2
  • 3
  • 4

既然rootIndex Changed了,为什么还需要给rootIndex赋值呢?导致多次打印。

效果如下

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/764655
推荐阅读
相关标签
  

闽ICP备14008679号