QML:如何将文件从资源管理器拖到我的 Qt Quick 应用程序?
QML: How to drag file from explorer to my Qt Quick application?
我正在 运行在桌面 Linux (KDE) 上安装 QML 应用程序。当文件被拖放到 QML 应用程序的主 window 上时,我需要获取文件路径和文件名作为文本(带或不带前缀 "file:///")。
如果我将文件从 Dolphin 文件管理器拖到 Firefox 的地址栏,文本 URI(例如,"file:///home/user/Downloads/file.txt")将被放入地址栏并在 Firefox 中打开该文件。这表明文件的拖动信息可从 OS 获得。
我可以使用我构建的 QML 应用程序(下面提供的代码)进行的另一项测试是 select 一些文本(比如在网页上)并将 selection 拖到我的应用程序的主 window。这有效,应用程序获取并存储文本 selection 包含的任何内容。
但是,我无法将 文件 拖放到我的 QML 应用程序中。我不明白为什么我可以拖动文本 selection 但不能拖动文件。我正在提供我的代码的工作示例。
在 KDE 上进行测试,当我将文件拖放到 QML 应用程序 window 上时,会调用 onDropped
方法。在那里我做了一个 console.log 并且 drop.text
是 empty (并且 drag.source 是空的)。
应该如何实现将文件(例如,从文件管理器)拖放到 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 示例。不幸的是,这些示例遇到了同样的问题,因此它们对解决问题没有帮助。但是,我已经读到我正在尝试做的事情是可以完成的。我只是还没有找到可行的解决方案。
这应该有效(在 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";
}
}
}
在 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";
}
}
}
Parameter "drop" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.
我正在 运行在桌面 Linux (KDE) 上安装 QML 应用程序。当文件被拖放到 QML 应用程序的主 window 上时,我需要获取文件路径和文件名作为文本(带或不带前缀 "file:///")。
如果我将文件从 Dolphin 文件管理器拖到 Firefox 的地址栏,文本 URI(例如,"file:///home/user/Downloads/file.txt")将被放入地址栏并在 Firefox 中打开该文件。这表明文件的拖动信息可从 OS 获得。
我可以使用我构建的 QML 应用程序(下面提供的代码)进行的另一项测试是 select 一些文本(比如在网页上)并将 selection 拖到我的应用程序的主 window。这有效,应用程序获取并存储文本 selection 包含的任何内容。
但是,我无法将 文件 拖放到我的 QML 应用程序中。我不明白为什么我可以拖动文本 selection 但不能拖动文件。我正在提供我的代码的工作示例。
在 KDE 上进行测试,当我将文件拖放到 QML 应用程序 window 上时,会调用 onDropped
方法。在那里我做了一个 console.log 并且 drop.text
是 empty (并且 drag.source 是空的)。
应该如何实现将文件(例如,从文件管理器)拖放到 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 示例。不幸的是,这些示例遇到了同样的问题,因此它们对解决问题没有帮助。但是,我已经读到我正在尝试做的事情是可以完成的。我只是还没有找到可行的解决方案。
这应该有效(在 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";
}
}
}
在 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";
}
}
}
Parameter "drop" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.