'QML: How to drag file from explorer to my Qt Quick application?
I'm running a QML app on desktop Linux (KDE). When a file is dropped onto the main window of the QML app, I need to get the file path and filename as text (with or without prefix "file:///").
If I drag a file from Dolphin file manager to Firefox's address bar, the text URI (e.g., "file:///home/user/Downloads/file.txt") is dropped into the address bar and the file opens in Firefox. This shows that the drag information for a file is available from the OS.
Another test I can do using the QML app I built (code provided below) is select some text (say on a webpage) and drag that selection onto my app's main window. This works and the app obtains and stores whatever the text selection contained.
However, I am not able to drag and drop files onto my QML application. I don't understand why I can drag a text selection but not a file. I'm providing a working example of my code.
Testing on KDE, when I drop a file onto the QML app window, the onDropped method is called. In there I do a console.log and drop.text is empty (and drag.source is null).
How is dragging and dropping of files (e.g., from a file manager) to the QML application supposed to be implemented?
and the 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
}
I found a related question, but it is the other way around: Drag file from application to explorer. Can my application do the copying?
I have also built and run the Qt examples. Unfortunately, the examples suffer from the same issue, so they aren't helpful in resolving the problem. However, I have read that what I'm trying to do can be done. I just haven't found a working solution.
Solution 1:[1]
In Qt 6, Use JavaScript functions with formal parameters instead.
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Honghe.Wu |
