Important: Please read the Qt Code of Conduct -

Dragging out to non-Qt desktop

  • Hello,
    I’m working on dragging and dropping capability in my desktop app, which consists of multiple QWidget.
    D&D works OK if it’s internal movement where the drop receiver is another QWidget.
    My question is how can I achieve the same functionality between the desktop app and non Qt app such as Window desktop where no qt app exists.
    How and where can I handle the dropEvent outside of Qt?

    Many thanks in advance for your help.

  • Moderators

    your question is very unclear.

    How and where can I handle the dropEvent outside of Qt?

    You shouldn't and you wont handle the drop outside your application. Similar to a copy and aste via clipboard you simply provide data to the operating system and let it do the multi-window drag-handling. The final target application which receives the drop handles the data on it's own.
    The only result you get is when your QDrag::exec() returnes and check the returned drop result.

  • Lifetime Qt Champion

    To drop to desktop, you must follow windows rules for the mimedata
    else it wont accept.

    This sample drags file from Qt to desktop / explorer
    It uses a native windows header. (#include <Shlobj.h>)

    #include "mainwindow.h"
    #include <QApplication>
    #include <QtGui>
    #include <Shlobj.h>
    class Widget : public QWidget {
      void mousePressEvent(QMouseEvent* e) {
        QPoint hotSpot = e->pos();
        QList<QUrl> strList;
        FILEDESCRIPTOR fd[ 1 ];
        strList.append( QUrl( "" ) );
        fgd.cItems = 1;
        fgd.fgd[ 0 ].dwFlags = FD_PROGRESSUI;
        wcscpy( fgd.fgd[ 0 ].cFileName, L"qtrules.url" );
        QMimeData* mimeData = new QMimeData;
        mimeData->setUrls( strList );
        mimeData->setData("text/plain", QByteArray( "" ) );
        mimeData->setData("text/html", QByteArray( "<!--StartFragment--><a href=\"\">The Gaspar Website</a><!--EndFragment-->" ) );
        mimeData->setData("FileName", QByteArray( "Gaspar Website.url" ) );
        mimeData->setData("FileGroupDescriptorW", QByteArray::fromRawData( ( const char* )&fgd, sizeof ( FILEGROUPDESCRIPTOR ) ) );
        mimeData->setData("FileContents", QByteArray( "[InternetShortcut]\r\nURL=" ) );
        QPixmap pixmap(":/images/imagelists/16x16/webpage.png");
        QDrag* drag = new QDrag(this);
        Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
        if (dropAction == Qt::MoveAction) {
    int main(int argc, char* argv[]) {
      QApplication app(argc, argv);
      Widget window;;
      return app.exec();

    Credits goes to

    alt text

  • @mrjj
    There should be a "Code Snippets" forum here, and this kind of post could be put there with a decent title.

  • Lifetime Qt Champion

    Yes, that would be great. I think we might be able to use the wiki for it since it already has samples.

  • Moderators

    Just a note: File drags to desktop can also be achieved using Qt classes only:

    1. start a drag containing all the needed mime-types
    2. create an empty QTemporaryFile with the target file-name and set it's file path to the mime-data (file-urls type)
    3. fill the temporary file once it is requested in the QMimeData::retrieveData() method (see the delayed encoding example)
    4. the OS copies the (temp-)file to the drop-position

  • Lifetime Qt Champion


    Did you try delayed encoding sample ?

    The sample will not work for me on win 7 or win 10.
    Tried 2 pc. Desktop/explorer wont accept.

    So i wonder if issue with my pcs or just dont work like that in newer Windows.

  • Moderators

    yes, but it's a while ago. I will give it a try.

  • Lifetime Qt Champion


    Super. Maybe i just do it wrong.
    I drag the export Button out from window. It show red stop sign.

  • Moderators

    the following (unoptimized code) works (Qt 5.9, Windows 7):

        : QMimeData()
        QString filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) % QDir::separator() % "Gaspar Website.url";
        m_File = new QFile( filePath, this );
        if( m_File && m_File->isOpen() )
    QStringList MimeData::formats() const
        return QMimeData::formats() << QLatin1String("text/uri-list");
    QVariant MimeData::retrieveData(const QString &mimeType, QVariant::Type type) const
        if( mimeType == QStringLiteral("text/uri-list") )
            // since this method may be called multiple during a single drag it's not necessary to also write to the file multiple times -> needs optimization
            if( m_File->open(QFile::WriteOnly) )
                m_File->write( QByteArray("[InternetShortcut]\r\nURL=") );
            return QVariant::fromValue<QUrl>( QUrl::fromLocalFile(QFileInfo(*m_File).absoluteFilePath()) );
            return QMimeData::retrieveData(mimeType, type);

    Although it seems there are some caveats:

    1. it stopped working when i set the path of the temp file into a subfolder in the temp-dir ... o.O
    2. the retrieveData() always requests the data with the type QVariant::QVariantList. But still it only works when i return a QUrl (not a QList) packed into the variant data.

    Very strange.

  • Lifetime Qt Champion


    Good work.
    Ehh so it likes only root of tmp dir ?? odd
    2: that is a bit odd but i guess it was only ment for 1 file then.

    Would it be possible to get the test code ?
    Want to see if win 10 likes it also :)

    This is nicer than the platform bound i found :) \o/

  • Moderators

    @mrjj said in Dragging out to non-Qt desktop:

    Would it be possible to get the test code ?

    thats actually all the code (despite the obvious header file).

    All i did additionally for testing was this:

    void MainWindow::mousePressEvent(QMouseEvent *event)
        MimeData* mimeData = new MimeData;
        QDrag drag( this );

    the mime type is text/uri-list, so a list does make sense. It also makes sense to copy multiple files at once to a folder in the filesystem explorer.
    I have no idea why it's not working. Would need to debug into Qt source code to make sure.

Log in to reply