【问题标题】:QML: How to drag file from explorer to my Qt Quick application?QML:如何将文件从资源管理器拖到我的 Qt Quick 应用程序?
【发布时间】:2020-01-12 21:01:31
【问题描述】:

我正在桌面 Linux (KDE) 上运行 QML 应用程序。当文件被拖放到 QML 应用程序的主窗口时,我需要以文本形式获取文件路径和文件名(带或不带前缀“file:///”)。

如果我将文件从 Dolphin 文件管理器拖到 Firefox 的地址栏,文本 URI(例如,“file:///home/user/Downloads/file.txt”)会被拖放到地址栏并打开文件在火狐中。这表明文件的拖动信息可从操作系统获得。

我可以使用我构建的 QML 应用程序(下面提供的代码)进行的另一项测试是选择一些文本(例如在网页上)并将该选择拖到我的应用程序的主窗口中。这有效,应用程序获取并存储所包含的任何文本选择。

但是,我无法将文件拖放到我的 QML 应用程序中。我不明白为什么我可以拖动文本选择而不是文件。我正在提供我的代码的工作示例。

在 KDE 上进行测试,当我将文件拖放到 QML 应用程序窗口时,会调用 onDropped 方法。在那里我做了一个 console.log 并且 drop.textempty (并且 drag.source 是 null)。

应该如何实现将文件(例如,从文件管理器)拖放到 QML 应用程序?

和 QML:

import QtQuick.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.0

ApplicationWindow {
    id: rootId
    visible: true
    title: "Drag Drop MRE"
    property int margin: 16
    minimumWidth: 600
    minimumHeight: 480

FileDialog {
        id: fileDialog
        title: "Choose File Attachment"
        folder: shortcuts.home
        onAccepted: {
            attachments.text += fileDialog.fileUrls + '\n'
            console.log("added attachment: " + fileDialog.fileUrls)
        }
    }
    DropArea{
    id: drop
    enabled: true
    anchors.fill: parent
    anchors.margins: margin
    Rectangle {
        anchors.fill: parent
        color: "green"
        visible: parent.containsDrag
    }
    onEntered: console.log("entered DropArea")
    onDropped:{
        attachments.text += drop.text + '\n'
        console.log("added attachment: " + drop.text)
        console.log("drag.source: " + drag.source)
    }
    Drag.dragType: Drag.Automatic
    GridLayout {
        id: mainLayout
        anchors.fill: parent
        anchors.margins: margin

        Label {
            text: "Drag Drop MRE"
            font.pixelSize: 16
            Layout.row: 1
            Layout.column: 1
        }

        GroupBox {
            Layout.row: 2
            Layout.column: 1
            id: gridBox
            Layout.fillWidth: true

            GridLayout {
                id: gridLayout
                rows: 1
                flow: GridLayout.TopToBottom
                anchors.fill: parent

                Label { text: "Attached files"
                }

                TextArea {
                    id: attachments
                    Layout.fillWidth: true
                    implicitHeight: 300
                }
            }
        }

        GroupBox {
            Layout.row: 3
            Layout.column: 1
            id: rowBox
            Layout.fillWidth: true
            Row {
                anchors.right: parent.right
                id: rowLayout
                Button {
                    id: attach_button
                    text: "Attach"
                    onClicked: fileDialog.open();

                }
                Button {
                    id: save_button
                    text: "Save"
                    onClicked: console.log(attachments.text)
                }
                Button {
                    id: exit_button
                    text: "Exit"
                    onClicked: Qt.quit()
                }
            }
        }

    }} // Grid Layout & Drop Area
}

我发现了一个相关的问题,但情况恰恰相反: Drag file from application to explorer. Can my application do the copying?

我还构建并运行了 Qt 示例。不幸的是,这些示例遇到了同样的问题,因此它们对解决问题没有帮助。但是,我已经读过我正在尝试做的事情是可以完成的。我只是还没有找到可行的解决方案。

【问题讨论】:

  • 您的问题主要与QML有关,PyQt5的部分与主要问题无关,因此我将其删除。
  • 我刚给你买了一杯咖啡。感谢您在 SO 上所做的所有工作。

标签: qt drag-and-drop qml qtquick2


【解决方案1】:

这应该可以工作(在 Windows 上测试):

Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Drop Area")

    DropArea {
        id: dropArea;
        anchors.fill: parent
        onEntered: {
            root.color = "gray";
            drag.accept (Qt.LinkAction);
        }
        onDropped: {
            console.log(drop.urls)
            root.color = "white"
        }
        onExited: {
            root.color = "white";
        }
    }
}

【讨论】:

  • 谢谢。现在测试。您使用的是哪些进口产品?
  • 谢谢。这也适用于 Linux。现在,如何将 drop.urls 分配给 QML 中的文本属性(例如标签或文本区域)?如果您想回答,请在此处查看问题:stackoverflow.com/q/59723408/463994
【解决方案2】:

在 Qt 6 中,改为使用带有形参的 JavaScript 函数。

Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Drop Area")

    DropArea {
        id: dropArea;
        anchors.fill: parent
        onEntered: (drag) => {
            root.color = "gray";
            drag.accept (Qt.LinkAction);
        }
        onDropped: (drop) => {
            console.log(drop.urls)
            root.color = "white"
        }
        onExited: {
            root.color = "white";
        }
    }
}

未声明参数“drop”。不推荐将参数注入信号处理程序。请改用带有形参的 JavaScript 函数。

参考:https://doc.qt.io/qt-6/qml-qtquick-droparea.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-15
    • 2020-10-29
    • 2011-04-01
    • 2012-10-19
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    相关资源
    最近更新 更多