Simple QML File Browser

qt-logoJust 4 fun. It takes a ListView, a FolderListModel and QQuickImageProvider to build a simple list file browser. First things First. The custom Icon Provider will answer QML requests for file icons.

// ***** IconProvider.h ******
#ifndef IMAGEPROVIDER_H
#define IMAGEPROVIDER_H
#include <QQuickImageProvider>
#include <QFileIconProvider>
#include <QMimeDatabase>
class IconProvider : public QQuickImageProvider
{
public:
    IconProvider();
    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);
protected:
    QFileIconProvider   m_provider;
    QMimeDatabase       m_mimeDB;
signals:
public slots:
};
#endif // IMAGEPROVIDER_H
// ***** IconProvider.cpp ****
#include "IconProvider.h"
IconProvider::IconProvider():QQuickImageProvider(QQuickImageProvider::Pixmap)
{ }
QPixmap IconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
    int width = requestedSize.width() > 0 ? requestedSize.width() : 64;
    int height = width;
    if (size) *size = QSize(width, height);
    if (QFileInfo(id).isDir()) return m_provider.icon(QFileIconProvider::Folder).pixmap(width,height);
    else  {
        QMimeType mime = m_mimeDB.mimeTypeForFile(id);
        if (QIcon::hasThemeIcon(mime.iconName())) return QIcon::fromTheme(mime.iconName()).pixmap(width,height);
        return m_provider.icon(QFileIconProvider::File).pixmap(width,height);
    }
}

In the Main we must inform the QML Engine of this IconProvider

// ***** main.cpp *****
#include <QApplication>
#include <QQmlApplicationEngine>
#include "IconProvider.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    engine.addImageProvider(QLatin1String("iconProvider"), new IconProvider());
    return app.exec();
}

The main window is built in QML with just a FileBrowser object

// ***** main.qml *****
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import Qt.labs.folderlistmodel 2.1

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Browse")
    FileBrowser {
        anchors.fill: parent
        path: "file:///home/" // let's start with the Home folder
    }
}

The FileBrowser use ListView with a FolderListModel to read data from filesystem and a simple delegate showing icon and filename. Header shows current path and a back button

// ***** FileBrowser.qml *****
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import Qt.labs.folderlistmodel 2.1
Item {
    id: browser
    property alias path: view.path
    width: 300
    height: 200
    ListView {
        id: view
        property var colors: ["white","#E0FFE0","white","#EEEEFF" ]
        property string path

        anchors.fill: parent
        model: FolderListModel {
            id: folder
            folder: view.path
        }
        delegate: FileDelegate { }
        headerPositioning: ListView.OverlayHeader
        header: Rectangle {
            width: browser.width
            height: 34
            color: "yellow"
            z:2
            Row {
                anchors.fill: parent
                Button {
                    width:32
                    height :32
                    text: "<<<"
                    onClicked: view.path = folder.parentFolder
                }
                Text {
                    text: view.path
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        footerPositioning: ListView.OverlayHeader
        footer: Rectangle {
            width: browser.width
            height: 34
            color: "yellow"
            z:2
            Row {
                anchors.fill: parent
                Text {
                    text: "["+folder.count+" Files]"
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
    }
}

Delegate is quite simple; it shows information about the file; A click on the row traverse the filesystem tree or launch the associated application.

// ***** FileDelegate.qml *****
import QtQuick 2.0
Rectangle {
    id:delegate
    width: view.width
    height:34
    color: view.colors[index & 3]
    Row { anchors.fill: parent
        Image {
            id: icon
            width: delegate.height - 2
            height:width
            source: "image://iconProvider/"+filePath
        }
        Text {
            text: fileName
            anchors.verticalCenter: parent.verticalCenter
        }
    }
    MouseArea {
        id:mouseArea
        anchors.fill: parent
        onClicked: fileIsDir ? view.path = fileURL : Qt.openUrlExternally(fileURL)
    }
}


You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *