gpt4 book ai didi

qt - 在两对 QGraphicsScene/QGraphicsView 之间拖放 QGraphicsItem

转载 作者:行者123 更新时间:2023-12-05 01:08:22 26 4
gpt4 key购买 nike

我有一个带有主窗口的应用程序,我在其中创建了一个 QGraphicsScene像这样:

DiagramWindow::DiagramWindow()
{
scene = new QGraphicsScene(0, 0, 600, 500);

然后在同一个程序上,我用另一个(不同的)QGraphicsScene 调用另一个窗口。这两个场景都有各自的 QGraphicsViews,我使用相同的自定义类在每个场景/窗口中绘制 QGraphicsItem。

现在我正在尝试 implement drag and drop在两个场景/窗口之间使用 this我得到了一个我认为与 this SO question 相似/相同的效果.基本上,当我将 QGraphicsItem 从第二个窗口/场景拖到主窗口时,它不会触发场景上的事件,但它会在主窗口的工具栏/边框中触发。

我的事件处理功能是:
void DiagramWindow::dragEnterEvent(QDragEnterEvent *event)
{
qDebug() << "I'm on the main window!";

event->acceptProposedAction();
}


void DiagramWindow::dropEvent(QDropEvent *event)
{
event->acceptProposedAction();
qDebug() << "got a drop!";
}

根据那里的答案,我必须 setAcceptDrops()在 QGraphicsScene(这是不可能的)中,所以诀窍似乎是重载 QGraphicsScene::dragMoveEvent() .由于我的 QGraphicsScene 没有特定的类(仅针对它的父 DiagramWindow),因此我不知道如何编写函数来针对场景的特定 dragMoveEvent() .

问题 1 我希望我能做这样的事情:
DiagramWindow->scene::dragMoveEvent()
{
...
}

但这当然是不可能的。我对 C++/Qt 真的很陌生,一般的工作流/语法动态仍然让我感到困惑。如何将我的 MainWindow 中的 QGraphicsScene 作为目标来编写事件处理函数?

问题 2 此外,我注意到通过重写这些事件处理函数,我(显然)失去了我在主窗口中的大部分功能——选择和移动 QGraphicsItems 不再有效。无论如何,只有当事件起源于第二个窗口时,我才能触发这些事件吗?我看过 QDrag->source() 但我也不明白它是如何工作的——比如,如果事件起源于第二个窗口,就这样做,否则,继续做你之前在做的事情——我实际上不知道是什么......:)

最佳答案

问题1

如果该事件由图表窗口接收,并希望它由 scene 接收当前由 view 显示,那么您应该做的是将事件传递给 View ,这会将其转换为 QGraphicsSceneDragDropEvent并将其重定向到场景:

void DiagramWindow::dragMoveEvent(event)
{
view->dragMoveEvent(event);
}

问题 2

对 Drag 事件了解不多,所以无济于事,但要根据 if 语句获得以前的行为,您应该这样做:
void MyDerivedClass::myEvent(event)
{
if(...)
// do specific behaviour
else
QBaseClass::myEvent(event); // default behaviour
}

假设你的类(class) MyDerivedClass (在您的情况下, DiagramWindow )继承自 Qt 类 QBaseClass (在您的情况下, QMainWindow ?),并且您要覆盖的事件方法是 myEvent() (在你的情况下, dragMoveEvent )。

工作示例:

我不知道你的类 DiagramWindow 是什么,但这里有一个工作示例,它应该为你提供所有必要的想法,使其在你的情况下工作。我建议你从这个工作示例开始,修改它以获得你需要的东西。

主.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();
}

场景.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

场景.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);
}

查看.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

查看.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);
}

在您的情况下,如果您需要明确调用 view->someDragDropEvent(event)来自您的 DiagramWindow ,那么你只需要更改 protected:public: .不过我觉得没必要,试试 没有 DiagramWindow 中重新实现拖放事件,它应该自动调用您的 View 之一。

关于qt - 在两对 QGraphicsScene/QGraphicsView 之间拖放 QGraphicsItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17216420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com