获取通过 FileDialog 选择的文件夹中的文件名列表

Get list of filenames in folder selected via FileDialog

我正在尝试提取使用 FileDialogselectFolder: true 选择的文件夹中所有图像文件的路径。 我能找到的所有示例都使用 FolderListModel 来静态分配文件夹。 我尝试在对话框中定义一个临时 FolderListModel 并在我从对话框中获得结果后更改其 folder 属性:

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
}

然而,这让我犯了错误:

Cannot assign object to property

我很困惑。在我看来,这似乎是一个相当标准的用例(例如,在列表中显示用户定义文件夹中的所有文件),但我找不到任何示例。

正确的做法是什么?

这里的问题与 Item 儿童在 QML 中的处理方式有关。一般来说每个Item都有一个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.

ItemItem 派生类型的情况下,属性 是 data

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.

感谢 data,您可以例如在 Item 派生类型中混合和匹配 TimerRectangle 以及其他可见和不可见类型。大概,FileDialogdefault属性不允许这样的自由度。因此,的解决方案从FileDialog中取出FolderListModel,以避免错误。

还应注意,简单地分配 folder 属性 并不能使用户有权查询模型。 I/O 操作可能需要时间,并且模型更新是异步发生的。因此,最好等待适当的事件,例如onFolderChanged,以确保模型已准备好被查询。结果,工作,示例可能如下所示:

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()
}