md612
md612

Reputation: 330

How to integrate ListView with FolderListModel using QML?

I am developing a file browser interface using QML. However, I find I cannot click any folder and the list covered the top button. I don't know what I did wrongly.

I used ListView and FolderListModel during the development. And I intend to make the interface as below and works like a file browser

The expected interface: enter image description here

Source Code:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Window 2.1
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.1
import Qt.labs.folderlistmodel 2.1
import QtMultimedia 5.0
import QtQuick.Controls.Styles 1.4
import Qt.labs.platform 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    property int index: 0
    property bool isActive: true

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Page1 {
            Rectangle {
                id:root;
                state:"hidden";
                color: "#212126";

                property string folderPathName: "file:///C:/";
                property bool rootPath:false;
                signal message(string msg);
                property int lineHeight: 90;
                signal selectedFolder(string folderPath);

                Button{
                    id:topLine;
                    text: "...";
                    width: root.width;
                    height: root.lineHeight;

                    onClicked: {
                        if (folderModel.parentFolder != ""){
                            root.folderPathName = folderModel.parentFolder;
                        }
                        else{
                            root.state = "hidden";
                        }
                    }
                }

                ListView{
                    id:listFileView;
                    anchors{
                        bottom: rectangleButton.top;
                        bottomMargin: 4;
                        right: root.right;
                        rightMargin: 0;
                        left: root.left;
                        leftMargin: 0;
                        top: topLine.bottom;
                        topMargin: 0;
                    }
                    clip:true;

                    delegate:Button{
                        text: fileName;
                        height:root.lineHeight;
                        width:root.width;

                        onClicked: {
                            if(folderModel.isFolder(index)){
                                root.folderPathName = folderModel.get(index, "fileURL");
                            }
                        }
                    }
                    model: FolderListModel{
                        id:folderModel;
                        objectName: "folderModel";
                        showDirs: true;
                        showFiles: true;
                        showDirsFirst: true;
                        nameFilters: ["*.mp3", "*.flac"];
                        folder:root.folderPathName;
                    }
                }

                  Rectangle {
                    id: rectangleButton;
                    height: 20;
                    color: "#212126";
                    anchors{
                        left: root.left;
                        leftMargin: 0;
                        right: root.right;
                        rightMargin: 0;
                        bottom: root.bottom;
                        bottomMargin: 0;
                    }

                    Rectangle{
                        id:rectWhiteLine;
                        anchors{
                            left:parent.left;
                            right: parent.right;
                            top:parent.top;
                        }
                        height: 2;
                        color:"white";
                    }
                }
            }
        }

        Page {

        }
    }

    footer: TabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex
        TabButton {
            text: qsTr("Main")
        }
        TabButton {
            text: qsTr("View")
        }
    }
}

After changing anchors{ bottom: rectangleButton.top; bottomMargin: 4; right: root.right; rightMargin: 0; left: root.left; leftMargin: 0; top: topLine.bottom; topMargin: 0; } to width: 200; height: 600, the interface turns to be below:

enter image description here

The folders cannot be clicked and they are not correctly aligned.

Upvotes: 2

Views: 2212

Answers (1)

Eligijus Pupeikis
Eligijus Pupeikis

Reputation: 1125

Maybe this example would be of any use to you. I have added "back" button that goes up one folder, and buttons that represent folders inside ListView are colored orange.

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
import Qt.labs.folderlistmodel 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        id: mainRect
        x: 20
        y: 20
        width: 300
        height: 450
        border.color: "black"
        radius: 30
        ListView {
            y: 30
            width: parent.width
            height: parent.height - 60
            clip: true
            model: FolderListModel {
                id: folderListModel
                showDirsFirst: true
//                nameFilters: ["*.mp3", "*.flac"]
            }

            delegate: Button {
                width: parent.width
                height: 50
                text: fileName
                onClicked: {
                    if (fileIsDir) {
                        folderListModel.folder = fileURL
                    }
                }
                background: Rectangle {
                    color: fileIsDir ? "orange" : "gray"
                    border.color: "black"
                }
            }
        }
    }
    Button {
        anchors.left: mainRect.right
        anchors.leftMargin: 5
        text: "back"
        onClicked: folderListModel.folder = folderListModel.parentFolder
    }
}

preview

To get clickable top area with "..." I would add Text there and Mouse Area to handle clicks:

Text {
    width: parent.width
    height: 30
    horizontalAlignment: Text.AlignHCenter
    verticalAlignment: Text.AlignVCenter
    text: "..."
    MouseArea {
        anchors.fill: parent
        onClicked: folderListModel.folder = folderListModel.parentFolder
    }
}

Add this code inside mainRect i.e. after line radius: 30.

Upvotes: 1

Related Questions