Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML: How to drag & drop files to application's main window?
Forum Updated to NodeBB v4.3 + New Features

QML: How to drag & drop files to application's main window?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
2 Posts 2 Posters 2.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    april_heard
    wrote on 12 Jan 2020, 18:49 last edited by april_heard 1 Dec 2020, 20:26
    #1

    Here is a working example that shows I can attach files with a FileDialog, but I cannot do the same via Drag & Drop. I'm running this QML app on desktop Linux (KDE).

    When a file is drug and dropped onto the main window, I need to get the full file path and filename as text.

    The code I have here actually functions on Mac, but I don't think I have done the correct implementation. Now that I have studied more examples while troubleshooting this, it appears that the method I used to implement drag and drop is intended for text selections. Indeed, my app will accept text selections dropped onto it. But it does not accept files (at least on Linux).

    When I drop a file onto the 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 (from Dolphin file manager) to the QML application window supposed to be implemented?

    Below are my python and qml files:

    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)
        }
        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: backend.dropaccept(attachments.text)
                    }
                    Button {
                        id: exit_button
                        text: "Exit"
                        onClicked: Qt.quit()
                    }
                }
            }
    
        }} // Grid Layout & Drop Area
    }
    
    

    python:

    import sys
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtCore import Qt, QCoreApplication, QObject, pyqtSlot
    from PyQt5.QtQml import QQmlApplicationEngine
    import os
    import re
    import getpass
    # from shutil import copyfile
    
    
    class Backend(QObject):
    
        def cleanup(self, string):
            return re.sub(r'\W+', '_', string)
    
        @pyqtSlot(str)
        def dropaccept(self, files):
            basepath = '/home/' + getpass.getuser()
    
            for file in files.split('\n'):
                if file.replace(' ', '') == '':
                    continue
                try:
                    file = file.replace('file://', '')
                    path_to_save = basepath + "/" + os.path.basename(file)
                    print("save path: " + path_to_save)
                except Exception:
                    print("bad file path")
    
    
    if __name__ == '__main__':
    
        backend = Backend()
    
        QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
        QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
        app = QApplication(sys.argv)
        engine = QQmlApplicationEngine('dragdropmre.qml')
        engine.rootContext().setContextProperty("backend", backend)
        sys.exit(app.exec_())
    
    
    1 Reply Last reply
    0
    • I Offline
      I Offline
      IntruderExcluder
      wrote on 13 Jan 2020, 09:08 last edited by
      #2

      The example below works fine both for text and files (Linux Mint with Nemo as file manager):

          DropArea {
              anchors.fill: parent
              onDropped: {
                  console.log(drop.text);
              }
          }
      
      1 Reply Last reply
      0

      1/2

      12 Jan 2020, 18:49

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved