Похоже, я столкнулся с двумя проблемами здесь. Первый объясняется в этом вопросе здесь Прием капель на QGraphicsScene . QGraphicsScene игнорирует DragAndDrops, которые не происходят над элементами. По сути, вы можете включить перетаскивание, но только для каждого элемента в отдельности, что все еще оставляет области, которые не покрыты элементом. Решение этой проблемы, кажется, состоит в том, чтобы перезаписать dragMoveEvent
void MyQGprahicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
Q_UNUSED(event)
// Overriding default dragMoveEvent in order to accept drops without items under them
}
Вторая проблема заключалась в том, что я пытался применить eventFilter к дочернему виджету, но, похоже, мне пришлось применить его в qApp, после чего все, похоже, работает, вероятно, потому, что qApp - это верхний объект QObject, куда будут попадать все события, когда они не обработаны.
#include "DragAndDropHandler.h"
bool DragAndDropHandler::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::DragEnter) {
handleDragEnter(dynamic_cast<QDragEnterEvent *>(event));
} else if(event->type() == QEvent::Drop) {
handleDrop(dynamic_cast<QDropEvent *>(event));
} else if(event->type() == QEvent::GraphicsSceneDrop) {
handleDrop(dynamic_cast<QGraphicsSceneDragDropEvent *>(event));
} else if (event->type() == QEvent::GraphicsSceneDragEnter) {
handleDragEnter(dynamic_cast<QGraphicsSceneDragDropEvent *>(event));
}
return QObject::eventFilter(obj, event);
}
void DragAndDropHandler::handleDragEnter(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
}
}
void DragAndDropHandler::handleDragEnter(QGraphicsSceneDragDropEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
}
}
void DragAndDropHandler::handleDrop(QDropEvent *event)
{
auto path = getUrlFromMimeData(event->mimeData());
event->acceptProposedAction();
emit imageDropped(path);
}
void DragAndDropHandler::handleDrop(QGraphicsSceneDragDropEvent *event)
{
auto path = getUrlFromMimeData(event->mimeData());
event->acceptProposedAction();
emit imageDropped(path);
}
QString DragAndDropHandler::getUrlFromMimeData(const QMimeData *mimeData) const
{
return mimeData->urls().first().toString().remove("file://");
}
И в конструкторе моего главного окна:
setAcceptDrops(true);
qApp->installEventFilter(mDragAndDropHandler);
connect(mDragAndDropHandler, &DragAndDropHandler::imageDropped, this, &MainWindow::loadImageFromFile);