Question1
If the event is received by the diagramWindow, and want it receive by the scene which is currently displayed by a view, then what you should do is pass the event to the view, that will convert it to a QGraphicsSceneDragDropEvent and redirect it to the scene:
void DiagramWindow::dragMoveEvent(event)
{
view->dragMoveEvent(event);
}
Question 2
Don't know much about Drag event so can't help, but to get the previous behaviour depending on a if statement, you should do:
void MyDerivedClass::myEvent(event)
{
if(...)
// do specific behaviour
else
QBaseClass::myEvent(event); // default behaviour
}
assuming your class MyDerivedClass(in your case, DiagramWindow) inherits from the Qt class QBaseClass (in your case, QMainWindow?), and the event method you want to override is myEvent() (in your case, dragMoveEvent).
Working example:
I don't know exacly what your class DiagramWindow is, but here is a working example that should give you all the necessary ideas to make it work in your case. I suggest you start from this working example, and modify it to get what you need.
main.cpp:
#include <QApplication>
#include "Scene.h"
#include "View.h"
int main(int argc, char * argv[])
{
QApplication app(argc,argv);
Scene * scene1 = new Scene(1);
View * view1 = new View(scene1, 1);
Scene * scene2 = new Scene(2);
View * view2 = new View(scene2,2);
view1->show();
view2->show();
return app.exec();
}
Scene.h:
#ifndef SCENE_H
#define SCENE_H
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
class Item;
class Item: public QGraphicsEllipseItem
{
public:
Item(int x,int y);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
class Scene: public QGraphicsScene
{
public:
Scene(int i);
protected:
virtual void dragEnterEvent ( QGraphicsSceneDragDropEvent * event );
virtual void dragLeaveEvent ( QGraphicsSceneDragDropEvent * event );
virtual void dragMoveEvent ( QGraphicsSceneDragDropEvent * event );
virtual void dropEvent ( QGraphicsSceneDragDropEvent * event );
int i;
};
#endif
Scene.cpp:
#include "Scene.h"
#include <QtDebug>
#include <QGraphicsSceneMouseEvent>
#include <QDrag>
#include <QMimeData>
Item::Item(int x, int y) : QGraphicsEllipseItem(x,y,50,50) {}
void Item::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "item mouse press";
// Create the mime data that will be transfered from one scene
// to another
QMimeData * mimeData = new QMimeData;
// In our case, the data will be the address of the item.
//
// Note: This is UNSAFE, and just for the sake of example. The
// good way to do it is to create your own mime type, containing
// all the information necessary to recreate an identical Item.
//
// This is because drag and drop is meant to work between
// applications, and the address of your item is not accessible
// by other applications (deferencing it would produce a
// segfault). It works fine in this case since you perform a
// drag and drop between different windows of the same
// application.
Item * item = this;
QByteArray byteArray(reinterpret_cast<char*>(&item),sizeof(Item*));
mimeData->setData("Item",byteArray);
// start the event
QDrag * drag = new QDrag(event->widget());
drag->setMimeData(mimeData);
drag->start();
}
Scene::Scene(int i) : i(i)
{
Item * item = new Item(100+100*i,100);
addItem(item);
}
void Scene::dragEnterEvent ( QGraphicsSceneDragDropEvent * event )
{
qDebug() << "scene" << i << "drag enter";
}
void Scene::dragLeaveEvent ( QGraphicsSceneDragDropEvent * event )
{
qDebug() << "scene" << i << "drag leave";
}
void Scene::dragMoveEvent ( QGraphicsSceneDragDropEvent * event )
{
qDebug() << "scene" << i << "drag move";
}
void Scene::dropEvent ( QGraphicsSceneDragDropEvent * event )
{
qDebug() << "scene" << i << "drop";
// retrieve the address of the item from the mime data
QByteArray byteArray = event->mimeData()->data("Item");
Item * item = *reinterpret_cast<Item**>(byteArray.data());
// add the item to the scene (automatically remove it from the
// other scene)
addItem(item);
}
View.h:
#ifndef VIEW_H
#define VIEW_H
#include <QGraphicsView>
#include "Scene.h"
class View: public QGraphicsView
{
public:
View(Scene * scene, int i);
protected:
virtual void dragEnterEvent ( QDragEnterEvent * event );
virtual void dragLeaveEvent ( QDragLeaveEvent * event );
virtual void dragMoveEvent ( QDragMoveEvent * event );
virtual void dropEvent ( QDropEvent * event );
private:
Scene * scene_;
int i;
};
#endif
View.cpp:
#include "View.h"
#include <QtDebug>
View::View(Scene * scene, int i) :
QGraphicsView(scene),
scene_(scene),
i(i)
{
}
void View::dragEnterEvent ( QDragEnterEvent * event )
{
qDebug() << "view" << i << "drag enter";
QGraphicsView::dragEnterEvent(event);
}
void View::dragLeaveEvent ( QDragLeaveEvent * event )
{
qDebug() << "view" << i <<"drag leave";
QGraphicsView::dragLeaveEvent(event);
}
void View::dragMoveEvent ( QDragMoveEvent * event )
{
qDebug() << "view" << i << "drag move";
QGraphicsView::dragMoveEvent(event);
}
void View::dropEvent ( QDropEvent * event )
{
qDebug() << "view" << i << "drop";
QGraphicsView::dropEvent(event);
}
In your case, if you need to explicitly call view->someDragDropEvent(event) from your DiagramWindow, then you just have to change the protected: to public:. But I don't think it is necessary, just try without reimplementing the drag and drop event in DiagramWindow, and it should automatically call the one of your view.