GPhilo
GPhilo

Reputation: 19123

Get list of filenames in folder selected via FileDialog

I'm trying to extract the path of all the image files in a folder that is selected with a FileDialog with selectFolder: true. All the examples I could find make use of a FolderListModel which gets the folder assigned statically. I tried defining a temporary FolderListModel inside the dialog and change its folder property once I have the result from the dialog:

FileDialog {
    id: select_folder_dialog

    FolderListModel {
        id: mdl
        nameFilters: ["*.jpg", "*jpeg", "*.png"]
    }

    onAccepted: {
        visible = false
        var files = []
        console.log(folder)
        mdl.folder(folder)
        text1.text = qsTr("%1 images selected.".arg(mdl.count))
    }
    title: "Select a folder containing image file(s) to classify"
    selectFolder: true
}

This however gets me the error:

Cannot assign object to property

I'm very confused. This seems to me a rather standard use-case (e.g. displaying in a list all the files in a user-defined folder), but I can't find any example.

What is the correct way to do this?

Upvotes: 1

Views: 1471

Answers (1)

BaCaRoZzo
BaCaRoZzo

Reputation: 7682

The issue here is related to the way children Items are treated in QML. Generally speaking each Item has a default property.

A default property is the property to which a value is assigned if an object is declared within another object's definition without declaring it as a value for a particular property.

In the case of Item and Item-derived types such a property is data which

allows you to freely mix visual children and resources in an item. If you assign a visual item to the data list it becomes a child and if you assign any other object type, it is added as a resource.

It's thank to data that you can e.g. mix and match Timer, Rectangle as well as other visible and not visible types inside an Item-derived type. Probably, the default property of FileDialog does not allow such degree of freedom. Hence, the solution it to take out FolderListModel from FileDialog, to avoid the error.

It should also be noted that simply assigning the folder property does not entitle the user to query the model. I/O operations can take time and model updates happen asynchronously. Thus, it is better to wait for appropriate events, e.g. onFolderChanged, to ensure that the model is ready to be queried. A resulting, working, example could look like the following:

import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import Qt.labs.folderlistmodel 2.1

Window {
    title: qsTr("Test dialog")
    visible: true
    width: 640
    height: 480

    FolderListModel {
        id: fileModel
        nameFilters: ["*.*"]

        onFolderChanged: { console.info(fileModel.get(0, "fileName")) }
    }

    FileDialog {
        id: dialog
        title: "Select a folder containing image file(s) to classify"
        selectFolder: true

        onAccepted: {
            dialog.close()
            fileModel.folder = folder
        }
    }

    Component.onCompleted: dialog.open()
}

Upvotes: 4

Related Questions