Qt 如何使用QML FileDialog选择多个文件和目录

Qt 如何使用QML FileDialog选择多个文件和目录,qt,qml,Qt,Qml,我从Qt5.5开始。 我希望在UI事务中尽可能多地使用QML。 我需要一个文件和目录选择器,可以选择多个对象,无论是文件或目录。 可以这样做,根据,QFileDialog需要设置为非本机。 根据,程序员无法强制QML FileDialog对象为非本机对象 必须使用C++来处理这个问题,还是有办法访问QML文件的属性,以便强制实现底层QFielDeLax,然后从QML中访问这个实例属性,以便在QML中实现解决方案? < P>编辑1:参见下面的注释。SR_是对的。我认为在C++中实现一些期望的行为是

我从Qt5.5开始。 我希望在UI事务中尽可能多地使用QML。 我需要一个文件和目录选择器,可以选择多个对象,无论是文件或目录。 可以这样做,根据,QFileDialog需要设置为非本机。 根据,程序员无法强制QML FileDialog对象为非本机对象

必须使用C++来处理这个问题,还是有办法访问QML文件的属性,以便强制实现底层QFielDeLax,然后从QML中访问这个实例属性,以便在QML中实现解决方案?

< P>编辑1:参见下面的注释。SR_是对的。我认为在C++中实现一些期望的行为是必要的。 编辑2:我以前的答案是错误的。将selectMultiple属性设置为true不是解决方案。因此,我更新了答案,以显示新的提案。有关此问题讨论的更多信息,请参阅下面的评论

下一个代码基于Qt示例,代码是到GitHub的

main.cpp

文件管理.h

filemanagement.cpp


要选择多个文件,可以将FileDialog的selectMultiple属性设置为true。但是,根据文档,您不能选择多个目录。@nfranklin,它在哪里说的?在下面。我已经测试了它,但它不起作用:您不能选择目录,即使在某些情况下,它看起来是选中的,请查看fileUrls值。根据文档,如果selectFolder为true,则默认为false,selectMultiple必须为false。哦,我明白了。。。你说得对。很抱歉我会尝试找到一个解决方案。经过几天的调查,我认为不可能以您想要的方式选择目录和文件:至少,只使用QML。这只是一个想法,但是你可以用C++实现你自己的集成来管理文件和目录的选择。我在GitHub有一个网站。代码应该很短。我猜可能有一种简单的方法可以以某种方式专门化组件行为,而不是像您所做的那样编写新的东西。让我们猜测这并不容易,因此需要编写一个自定义对话框。如果您修改您的答案以显示您的解决方案并跟踪错误的解决方案,我将接受。目前还不清楚您的第一个解决方案在没有阅读注释的情况下是否有效。@SR_uu好的,没问题。无论如何,我不仅仅是在寻找绿色标志;我想帮助你:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QFileSystemModel>
#include "filemanagement.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    FileManagement fileManagement;
    QQmlApplicationEngine engine;
    QFileSystemModel *fsm = new QFileSystemModel(&engine);
    fsm->setRootPath(QDir::homePath());
    fsm->setResolveSymlinks(true);
    engine.rootContext()->setContextProperty("fileManagement", &fileManagement);
    engine.rootContext()->setContextProperty("fileSystemModel", fsm);
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQml.Models 2.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("File System")

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    Row {
        id: row
        anchors.top: parent.top
        anchors.topMargin: 12
        anchors.horizontalCenter: parent.horizontalCenter

        ExclusiveGroup {
            id: eg
        }

        Repeater {
            model: [ "None", "Single", "Extended", "Multi", "Contig."]
            Button {
                text: modelData
                exclusiveGroup: eg
                checkable: true
                checked: index === 1
                onClicked: view.selectionMode = index
            }
        }
    }

    ItemSelectionModel {
        id: sel
        model: fileSystemModel
        onSelectionChanged: {
            console.log("selected", selected)
            console.log("deselected", deselected)
            fileManagement.printFileNames(model, selectedIndexes)
        }
        onCurrentChanged: console.log("current", current)
    }

    TreeView {
        id: view
        anchors.fill: parent
        anchors.margins: 2 * 12 + row.height
        model: fileSystemModel
        selection: sel

        onCurrentIndexChanged: console.log("current index", currentIndex)

        TableViewColumn {
            title: "Name"
            role: "fileName"
            resizable: true
        }

        TableViewColumn {
            title: "Permissions"
            role: "filePermissions"
            resizable: true
        }

        onClicked: {
            console.log("clicked", index)            
            fileManagement.printPath(index.model, index)
        }
        onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index)
    }

    Component.onCompleted: fileManagement.test()
}
#ifndef FILEMANAGEMENT_H
#define FILEMANAGEMENT_H

#include <QObject>
#include <QDebug>
#include <QFileSystemModel>

class FileManagement : public QObject
{
    Q_OBJECT
public:
    explicit FileManagement(QObject *parent = 0);

    Q_INVOKABLE bool printPath(QFileSystemModel* fileSystemModel,
                               const QModelIndex &modelIndex);

    Q_INVOKABLE bool printFileNames(QFileSystemModel* fileSystemModel,
                                    QList<QModelIndex> modelIndexList);

signals:

public slots:

    void test() {
        qDebug() << "Called the C++ slot";
    }
};

#endif // FILEMANAGEMENT_H
#include "filemanagement.h"

FileManagement::FileManagement(QObject *parent) : QObject(parent)
{

}

bool FileManagement::printPath(QFileSystemModel* fileSystemModel,
                       const QModelIndex &modelIndex) {
    qDebug() << "+ File path: " << fileSystemModel->filePath(modelIndex);
    return true;
}

bool FileManagement::printFileNames(QFileSystemModel* fileSystemModel,
                            QList<QModelIndex> modelIndexList) {
    qDebug() << "+ " << modelIndexList.size() << " items selected: ";
    QList<QModelIndex>::iterator i;
    for (i = modelIndexList.begin(); i != modelIndexList.end(); ++i) {
        qDebug() << "++ File name: " << fileSystemModel->fileName(*i);
    }

    return true;
}