Results 1 to 7 of 7

Thread: Drag and drop per key press?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2020
    Posts
    19
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Drag and drop per key press?

    I want to achieve a drag and drop from my application to the OS window system (Windows 10), but not by using the mouse. Instead, the content will be selected by a button press and should automatically be drag-dropped to the window under the mouse cursor.

    I wrote a test class, for a regular drag-drop with the mouse, and for the same with a key press:

    Qt Code:
    1. #include <QtCore/QList>
    2. #include <QtCore/QUrl>
    3. #include <QtCore/QMimeData>
    4. #include <QtWidgets/QApplication>
    5. #include <QtWidgets/QMainWindow>
    6. #include <QtGui/QDrag>
    7. #include <QtGui/QKeyEvent>
    8. #include <QtGui/QMouseEvent>
    9. #include <QtGui/QScreen>
    10.  
    11. class DragDropTester: public QMainWindow {
    12. QUrl m_file;
    13.  
    14. void move_file() {
    15. auto* mime_data = new QMimeData;
    16. mime_data->setUrls(QList<QUrl> { } << m_file);
    17.  
    18. auto* screen = QApplication::primaryScreen();
    19. auto mouse_pos = QCursor::pos();
    20. QDropEvent drop_event { mouse_pos, Qt::MoveAction, mime_data, Qt::NoButton, Qt::NoModifier };
    21. QApplication::sendEvent(screen, &drop_event);
    22. }
    23.  
    24. protected:
    25. void keyPressEvent(QKeyEvent* e) override {
    26. switch (e->key()) {
    27. case Qt::Key_M:
    28. move_file();
    29. break;
    30. default:
    31. QMainWindow::keyPressEvent(e);
    32. }
    33. }
    34.  
    35. void mousePressEvent(QMouseEvent*) override {
    36. auto* mime = new QMimeData;
    37. mime->setUrls(QList<QUrl> { } << m_file);
    38.  
    39. auto* drag = new QDrag { this };
    40. drag->setMimeData(mime);
    41.  
    42. drag->exec();
    43. }
    44.  
    45. public:
    46. DragDropTester(const QString& path) : QMainWindow { } {
    47. m_file = QUrl::fromLocalFile(path);
    48. setFixedSize(400, 400);
    49. show();
    50. }
    51.  
    52. };
    To copy to clipboard, switch view to plain text mode 

    The drag & drop with mouse using QDrag works, but the key version does not.
    Unfortunately it looks like QDrag is implemented to always listen for mouse release event to determine when to finalize the drop, instead of providing a ".drop()" function or similar ..

    I looked around in the doc and I think I need to construct and handle my own QDropEvent, which I tried to do in the above code, but it does not work.

    In particular I am unsure about several points:

    • The QDropEvent::QDropEvent(.. doc says "Constructs a drop event ... at the point specified by pos in the destination widget's coordinate system". Is the "destination" widget the "receiver" that I pass to my QDropEvent? I not, what would the correct pos be to provide the global mouse position on the OS desktop?
    • I am not really sure if sendEvent does what I want ?
    • The QCoreApplication::sendEvent(.. doc says "Sends event event directly to receiver receiver, ...". receiver is a QObject* .. I don't know if passing QScreen* to this makes sense? I assume the receiver must implement dropEvent(), but QScreen is not a widget ... This is probably wrong, but I don't know what else to pass as receiver, what would the correct receiver be in my case?


    Or maybe there is completely different way and trying to construct / handle QDropEvent is wrong? Help appreciated!


    Edit: A second idea: I could simulate the mouse events by sending them from the key events, but I am also stuck trying to get this to work:

    Qt Code:
    1. // in keyPressEvent ...
    2. case Qt::Key_M:
    3. if (!e->isAutoRepeat()) {
    4. QMouseEvent mouse_event { QEvent::MouseButtonPress, mapFromGlobal(QCursor::pos()),
    5. Qt::LeftButton, Qt::NoButton, Qt::NoModifier };
    6. QApplication::sendEvent(this, &mouse_event);
    7. }
    8. break;
    To copy to clipboard, switch view to plain text mode 

    This triggers the mouse event, but the QDrag does not show up (i.e. nothing happens and the icon that I get when I instead click the mouse does not show). Maybe because the mouse button needs to be held down, but I don't see any event setting for this
    Last edited by Maryu; 6th September 2020 at 22:01.

Similar Threads

  1. Replies: 0
    Last Post: 28th June 2019, 13:36
  2. Replies: 2
    Last Post: 30th January 2014, 07:46
  3. Replies: 0
    Last Post: 7th January 2012, 16:20
  4. Replies: 2
    Last Post: 13th October 2010, 22:51
  5. Replies: 0
    Last Post: 4th May 2010, 11:24

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.