Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Making a QML Element "droppable"
Forum Updated to NodeBB v4.3 + New Features

Making a QML Element "droppable"

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 2.7k 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.
  • F Offline
    F Offline
    Fuzz1985
    wrote on last edited by
    #1

    Hi guys,

    First post - hope you can help!

    Basically I would like to make one of my QML elements be able to receive files from a File Manager/Desktop by dragging them into my application. I'm sure I need to create the QML element in Qt first so I can override dragEnterEvent and dropEvent, and although dragEnterEvent seems to work OK, it appears dropEvent never seems to run.

    From my code below, the debug console reports "dragEnterEvent entered" and "Proposed Action accepted" whenever I drag into my QML element, however displays the Windows unavailable cursor. The console does NOT display "dropEvent entered" at any point.

    Hopefully I'm just missing something stupid, but can't for the life of me work it out! Am I going the right way about things here? And is what I am trying to acheive possible? It works fine with regular QWidgets but not when using QML elements!

    Thanks in advance.

    @//main.cpp
    #include <QtGui/QApplication>
    #include "qmlapplicationviewer.h"
    #include <QtDeclarative/QDeclarativeContext>
    #include "mainwindow.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    MainWindow mw;
    
    mw.setWindowFlags(Qt::FramelessWindowHint) ;
    mw.setAttribute(Qt::WA_TranslucentBackground);
    mw.setStyleSheet("background:transparent");
    
    mw.show();
    
    return app.exec();
    

    }@

    @//mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtDeclarative>
    #include "testwidget.h"

    class MainWindow : public QDeclarativeView
    {
    Q_OBJECT
    public:
    QPoint mpos;
    bool m_canMoveWindow;

    explicit MainWindow(QWidget *parent = 0);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    

    signals:

    public slots:

    };

    #endif // MAINWINDOW_H@

    @//mainwindow.cpp
    #include "mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QDeclarativeView(parent)
    {
    rootContext()->setContextProperty("mainwnd",this);
    setResizeMode(QDeclarativeView::SizeRootObjectToView);
    setSource(QUrl("qml/untitled/main.qml"));

    TestWidget *tw = new TestWidget(this);
    tw->show();
    

    }

    void MainWindow::mousePressEvent(QMouseEvent *event)
    {
    if(event->button() != Qt::LeftButton)
    return;

    mpos = event->pos();
    
    if(mpos.y() <= 20)
        m_canMoveWindow = true;
    
    QDeclarativeView::mousePressEvent(event);
    

    }

    void MainWindow::mouseMoveEvent(QMouseEvent *event)
    {
    QDeclarativeView::mouseMoveEvent(event);

    if(!m_canMoveWindow)
        return;
    
    move(pos() + event->pos() - mpos);
    

    }

    void MainWindow::mouseReleaseEvent(QMouseEvent *event)
    {
    m_canMoveWindow = false;

    QDeclarativeView::mouseReleaseEvent(event);
    

    }@

    @//testwidget.h
    #ifndef TESTWIDGET_H
    #define TESTWIDGET_H

    #include <QWidget>
    #include <QtDeclarative>

    class TestWidget : public QDeclarativeView
    {
    Q_OBJECT
    public:
    explicit TestWidget(QWidget *parent = 0);
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);

    signals:

    public slots:

    };

    #endif // TESTWIDGET_H@

    @//testwidget.cpp
    #include "testwidget.h"

    TestWidget::TestWidget(QWidget *parent) :
    QDeclarativeView(parent)
    {
    setFixedSize(100, 62);
    setGeometry(20, 40, 100, 62);
    rootContext()->setContextProperty("dropbox",this);
    setResizeMode(QDeclarativeView::SizeRootObjectToView);
    setSource(QUrl("qml/untitled/DropBox.qml"));

    setAcceptDrops(true);
    

    }

    void TestWidget::dragEnterEvent(QDragEnterEvent *event)
    {
    qDebug() << "dragEnterEvent entered";

    if(event->mimeData()->hasUrls())
    {
        event->acceptProposedAction();
        qDebug() << "Proposed Action accepted";
    }
    

    }

    void TestWidget::dropEvent(QDropEvent *event)
    {
    qDebug() << "dropEvent entered";

    QList<QUrl> droppedUrls = event->mimeData()->urls();
    
    for(int i = 0; i < droppedUrls.size(); i++) {
        QString localPath = droppedUrls[i].toLocalFile&#40;&#41;;
        QFileInfo fileInfo(localPath);
        qDebug() << fileInfo.absoluteFilePath();
    }
    
    event->acceptProposedAction();
    

    }@

    @//main.qml
    // import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
    import QtQuick 1.1

    Rectangle {
    width: 360; height: 360
    color: "white"
    border.width: 2; border.color: "black"

    Rectangle {
        width: parent.width; height: 20
        color: "black"
    
        Text {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            color: "white"
            text: "My App"
        }
    }
    
    /*DropBox {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }*/
    

    }@

    @//DropBox.qml
    // import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
    import QtQuick 1.1

    Rectangle {
    width: 100; height: 62
    border.color: "black"; border.width: 1

    Text {
        text: "Drop Box"
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }
    

    }@

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Fuzz1985
      wrote on last edited by
      #2

      Thanks for anyone who took the time to read this, however I have figured it out - finally!

      I guess QDeclarativeView cannot be dragged onto, so I changed my TestWidget class to inherit QWidget instead, and placed the QDeclarative object in the QWidget. In the dragEnterEvent for the QWidget, I made the QDeclarativeView transparent to mouse events (so I was always dragging onto the QWidget instead of the QDeclarativeView). I then removed this attribute in the dragLeaveEvent and dropEvent.

      This did the trick! New code for TestWidget below:

      @//testwidget.cpp

      #include "testwidget.h"

      TestWidget::TestWidget(QWidget *parent) :
      QWidget(parent)
      {
      qc = new QDeclarativeView(this);
      qc->setFixedSize(100, 62);
      qc->setGeometry(20, 60, 100, 62);
      qc->rootContext()->setContextProperty("dropbox",this);
      qc->setResizeMode(QDeclarativeView::SizeRootObjectToView);
      qc->setSource(QUrl("qml/untitled/DropBox.qml"));

      this->setAcceptDrops(true);
      

      }

      void TestWidget::dragEnterEvent(QDragEnterEvent *event)
      {
      qc->setAttribute(Qt::WA_TransparentForMouseEvents, true);

      qDebug() << "dragEnterEvent entered";
      
      if(event->mimeData()->hasUrls())
      {
          event->acceptProposedAction();
          qDebug() << "Proposed Action accepted";
      }
      

      }

      void TestWidget::dragLeaveEvent(QDragLeaveEvent *)
      {
      qc->setAttribute(Qt::WA_TransparentForMouseEvents, false);
      }

      void TestWidget::dropEvent(QDropEvent *event)
      {
      qDebug() << "dropEvent entered";

      QList<QUrl> droppedUrls = event->mimeData()->urls();
      
      for(int i = 0; i < droppedUrls.size(); i++) {
          QString localPath = droppedUrls[i].toLocalFile&#40;&#41;;
          QFileInfo fileInfo(localPath&#41;;
          qDebug() << fileInfo.absoluteFilePath();
      }
      
      event->acceptProposedAction();
      
      qc->setAttribute(Qt::WA_TransparentForMouseEvents, false);
      

      }@

      @//testwidget.h

      #ifndef TESTWIDGET_H
      #define TESTWIDGET_H

      #include <QWidget>
      #include <QtDeclarative>

      class TestWidget : public QWidget
      {
      Q_OBJECT
      public:
      QDeclarativeView *qc;

      explicit TestWidget(QWidget *parent = 0);
      void dragEnterEvent(QDragEnterEvent *event);
      void dragLeaveEvent(QDragLeaveEvent *event);
      void dropEvent(QDropEvent *event);
      

      signals:

      public slots:

      };

      #endif // TESTWIDGET_H@

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #3

        Oh good, I was about to reply now I got back from classes.

        Nice solution, thanks for sharing.

        (Z(:^

        1 Reply Last reply
        0

        • Login

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