PDA

View Full Version : I receive QDragEnterEvent, but not QDropEvent



Ishmael
26th October 2009, 19:40
I am trying to drag an icon from the desktop onto my application, which is nothing more than an empty QGraphicsView window. I receive a QDragEnterEvent, but when I release the mouse button, I do not receive a QDropEvent. What am I doing wrong? Here's my simplified code. Thanks for your help!


#include <QtGui/QApplication>
#include <QMainWindow>
#include <QGraphicsView>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QGraphicsSceneDragDropEvent>

class MyGraphicsView : public QGraphicsView
{
//Q_OBJECT // Do I need Q_OBJECT?

public:
MyGraphicsView(QGraphicsScene *parent=0);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
//void dropEvent(QGraphicsSceneDragDropEvent *event);
};

MyGraphicsView::MyGraphicsView(QGraphicsScene *parent)
: QGraphicsView(parent)
{
setAcceptDrops(true);
}

void MyGraphicsView::dragEnterEvent(QDragEnterEvent *event)
{
//event->setDropAction(Qt::IgnoreAction);
event->accept();
}

//void MyGraphicsView::dropEvent(QGraphicsSceneDragDropEv ent *event)
//{
// event->accept();
// qDebug("here");
//}

void MyGraphicsView::dropEvent(QDropEvent *event)
{
qDebug("here"); // I NEVER GET TO HERE
event->accept();
}

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

QGraphicsScene *scene = new QGraphicsScene;
MyGraphicsView *view = new MyGraphicsView(scene);
view->setAcceptDrops(true);

window.setCentralWidget(view);
window.resize(640, 480);
window.setAcceptDrops(true);
window.show();

return app.exec();
}

wysota
26th October 2009, 22:43
Call
view->viewport()->setAcceptDrops(true);

Ishmael
26th October 2009, 23:20
Thanks for the response. Unfortunately, it still doesn't work. Do I need to do something with QGraphicsSceneDropEvent?

wysota
27th October 2009, 00:23
Do you get drag move events? It's highly possible the default implementation rejects drags there and hence no drop events are delivered. From what I see in the code, that's exactly what happens - by default you will only get drop events if the scene accepts a drag move event. If you want something else, you have to reimplement dragMoveEvent for the view and accept the drags there.

Ishmael
27th October 2009, 01:17
You were right! It's so non-intuitive, I never would have figured it out on my own. Thanks a million for your help!

For anyone else who might have this problem, here's what I added to my code to get it to accept Drop events. Why I have to accept Move events to get a Drop event, I shall never know, but here it is! :-)


void MyGraphicsView::dragMoveEvent(QDragMoveEvent *event)
{
event->accept();
}



// And then to extract the filename(s) for the dragged icon(s)
// Taken from "dropsite" example.
void MyGraphicsView::dropEvent(QDropEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if (mimeData->hasUrls()) {
QList<QUrl> urlList = mimeData->urls();
QString filenames;
for (int i = 0; i < urlList.size() && i < 32; ++i) {
QString url = urlList.at(i).path();
filenames += url + QString("\n");
}
}

wysota
27th October 2009, 01:25
It's so non-intuitive, I never would have figured it out on my own.
Actually I'd say it is quite intuitive once you know how dragging works in Qt and what the relation between the graphics view and graphics scene is.


Why I have to accept Move events to get a Drop event, I shall never know, but here it is! :-)
Because you might want to accept drops only on certain areas of a widget and the user needs a visual hint to know if he can make a drop at a certain place before he decides to do it.