Poor performance problem



  • Hi, everyone!
    I am a newer. I try to write a file browser using QML. But has some problems.
    If a folder (for example /usr/bin) has many files, my app will take a long time to refresh the listview.
    I would like to know what causes poor performance.Thanks.
    Here is my code:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QtQml>
    #include <QQmlContext>
    #include "mainclass.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        qmlRegisterType<MainClass>("per.pqy.mc", 1, 0, "MainClass");
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
    }
    
    #ifndef MAINCLASS_H
    #define MAINCLASS_H
    
    #include <QObject>
    #include <QStringList>
    #include <QQmlContext>
    #include <QFile>
    #include <QDateTime>
    
    class MainClass : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString currentPath READ currentPath WRITE setCurrentPath NOTIFY currentPathChanged)
        Q_PROPERTY(QStringList filesList READ filesList )
        Q_PROPERTY(QStringList  filesInfoList READ filesInfoList)
        Q_PROPERTY(int filesCount READ filesCount)
    public:
        explicit MainClass(QObject *parent = 0, QString root = "/");
        QString currentPath();
        void setCurrentPath(const QString &path);
        QStringList filesList();
        QStringList filesInfoList();
        int filesCount();
    
    signals:
        void currentPathChanged();
    
    public slots:
        void setCurrentPath(int index);
    
    private:
        QStringList _currentFilesList;
        QString _currentPath;
        QString qtPerm2unix(QFile::Permissions p);
        QString qtFileSize(qint64 s);
        QString qtDate(QDateTime d);
    };
    
    #endif // MAINCLASS_H
    
    #include "mainclass.h"
    #include <QDir>
    #include <QFile>
    
    MainClass::MainClass(QObject *parent,QString root) : QObject(parent),_currentPath(root)
    {
        _currentFilesList = QDir(_currentPath).entryList(QDir::AllEntries|QDir::NoDot,QDir::DirsFirst);
        emit currentPathChanged();
    }
    
    QString MainClass::currentPath()
    {
        return _currentPath;
    }
    
    void MainClass::setCurrentPath(const QString &path)\
    {
        _currentPath = path;
        _currentFilesList = QDir(_currentPath).entryList(QDir::AllEntries|QDir::NoDot,QDir::DirsFirst);
        emit currentPathChanged();
    }
    
    QStringList MainClass::filesList()
    {
        return _currentFilesList;
    }
    
    QStringList MainClass::filesInfoList()
    {
        QFileInfoList infoList = QDir(_currentPath).entryInfoList(QDir::AllEntries|QDir::NoDot,QDir::DirsFirst);
        QStringList finfoList ;
        foreach(QFileInfo f,infoList){
            finfoList << qtPerm2unix(f.permissions()) + "    " + (f.isDir()?"    ":qtFileSize(f.size())) + "    "+ qtDate(f.lastModified());
        }
        return finfoList;
    }
    
    QString MainClass::qtPerm2unix(QFileDevice::Permissions p)
    {
        QString str;
        if(p&QFileDevice::ReadOwner)
            str+="r";
        else
            str+="-";
        if(p&QFileDevice::WriteOwner)
            str+="w";
        else
            str+="-";
        if(p&QFileDevice::ExeOwner)
            str+="x";
        else
            str+="-";
        if(p&QFileDevice::ReadGroup)
            str+="r";
        else
            str+="-";
        if(p&QFileDevice::WriteGroup)
            str+="w";
        else
            str+="-";
        if(p&QFileDevice::ExeGroup)
            str+="x";
        else
            str+="-";
        if(p&QFileDevice::ReadOther)
            str+="r";
        else
            str+="-";
        if(p&QFileDevice::WriteOther)
            str+="w";
        else
            str+="-";
        if(p&QFileDevice::ExeOther)
            str+="x";
        else
            str+="-";
        return str;
    }
    
    QString MainClass::qtFileSize(qint64 s)
    {
        QString str;
        if(s>1024l*1024l*1024l)
            str = QString::number(s/1024.0/1024.0/1024.0,'g',2)+"G";
        else if(s>1024l*1024l)
            str = QString::number(s/1024.0/1024.0,'g',2)+"M";
        else if(s>1024l)
            str = QString::number(s/1024.0,'g',2)+"K";
        else
            str = QString::number(s)+"B";
        return str;
    }
    
    QString MainClass::qtDate(QDateTime d)
    {
        return d.toString("dd/MM/yyyy");
    }
    
    int MainClass::filesCount()
    {
        return _currentFilesList.count();
    }
    
    void MainClass::setCurrentPath(int index)
    {
      QFileInfo finfo(_currentPath,_currentFilesList[index]);
      if(finfo.isDir()){
          _currentPath += "/";
          _currentPath += _currentFilesList[index];
          _currentFilesList = QDir(_currentPath).entryList(QDir::AllEntries|QDir::NoDot,QDir::DirsFirst);
          emit currentPathChanged();
    
      }
    }
    
    
    import QtQuick 2.5
    import QtQuick.Controls 1.4
    import per.pqy.mc 1.0
    
    
    ApplicationWindow {
        visible: true
        width: 480
        height: 800
        title: qsTr("Hello World")
    
        function setModel(){
                        model.clear();
                        for(var i =0;i<mc.filesCount;i++){
                                model.append({"name":mc.filesList[i],"info":mc.filesInfoList[i]})
                        }
                    }
    
        MainClass {
            id:mc
            onCurrentPathChanged: setModel()
    
        }
    
    
        Rectangle {
            id: root
            anchors.fill: parent
            color: "#aa040404"
    
    
    
            ListModel {
                id: model
    
    
            }
    
            ListView {
                id: list
               anchors.fill: parent
             //  anchors.top: menu.bottom
               //anchors.bottom: parent.bottom
              // width: parent.width
               highlightRangeMode: ListView.NoHighlightRange
               flickDeceleration: 3000
               maximumFlickVelocity: 8000
               spacing: 1
               clip: true
               Component.onCompleted: setModel()
    
    
    
    
               model:model
               delegate: Rectangle {
                    height: root.height/15
                    width: root.width
                    MouseArea {
                      anchors.fill: parent
                      onClicked: mc.setCurrentPath(index)
    
                    }
    
    
                     color: "#aa000000"
                     Text { id: t1; text: name ;color: "white";height: parent.height*2/3;font.pixelSize: height*4/7}
                     Text { anchors.top: t1.bottom; anchors.bottom: parent.bottom; text: info; color: "white";height: parent.height*1/3 }
                }
            }
        }
    }
    
    
    

  • Lifetime Qt Champion

    Hi,

    Why not use QFileSystemModel ? It's designed to browse a file system and is threaded to avoid blocking the GUI thread.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.