问题1
如果事件已经被 diagramWindow
接收,但是想要让当前由 view
显示的 scene
也接收到该事件,那么你需要将该事件传递给视图,它将把它转换为 QGraphicsSceneDragDropEvent
并将其重定向到场景:
void DiagramWindow::dragMoveEvent(event)
{
view->dragMoveEvent(event);
}
问题2
对于拖动事件我不是很了解,无法提供帮助,但如果想要根据if语句来获得先前的行为,应该这样做:
void MyDerivedClass::myEvent(event)
{
if(...)
else
QBaseClass::myEvent(event);
}
假设你的类
MyDerivedClass
(在你的情况下,是
DiagramWindow
)继承自 Qt 类
QBaseClass
(在你的情况下,是
QMainWindow
),并且你想要重写的事件方法是
myEvent()
(在你的情况下,是
dragMoveEvent
)。
以下是一个可行的示例,可以为你提供所有必要的思路以使其在你的情况下工作。我建议你从这个可行的示例开始,并进行修改以满足你的需求。
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";
QMimeData * mimeData = new QMimeData;
Item * item = this;
QByteArray byteArray(reinterpret_cast<char*>(&item),sizeof(Item*));
mimeData->setData("Item",byteArray);
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";
QByteArray byteArray = event->mimeData()->data("Item");
Item * item = *reinterpret_cast<Item**>(byteArray.data());
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);
}
在您的情况下,如果您需要从
DiagramWindow
中显式调用
view->someDragDropEvent(event)
,那么您只需要将
protected:
更改为
public:
。但我认为这并不是必要的,只需在
DiagramWindow
中
不重新实现拖放事件,它应该会自动调用您视图中的拖放事件。
dragMoveEvent
需要一个QGraphicsSceneDragDropEvent
类型的事件,而DiagramWindow的dragMoveEvent
是QDragEnterEvent
类型的。因此,似乎需要进行某种类型的_转换_。有什么想法吗? - Joum