PDA

View Full Version : Drag & Drop and Context Menu problem QGraphicsScene



onurozcelik
19th August 2010, 09:12
I developing some kind of builder for our project. I want to use both drag and drop support and context menu in my application. Currently I use drag and drop support but no luck with context menu. Below is my builders gui.

http://img210.imageshack.us/img210/1858/trackbuilder2.jpg

Left side my gui is toolbox. I am draging and droping widgets to the right side(QGraphicsScene) and I also want to use context menu inside QGraphicsScene. I use context menu inside graphics scene before. But before I did not use drap & drop operations. I write proper code but it does not work. What is missing?(Is it related drag & drop). Below is my code files.



//#dragwidget.cpp - Toolbox widgets
#include "dragwidget.h"

DragWidget::DragWidget(void)
{
}

DragWidget::~DragWidget(void)
{
}

void DragWidget::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
QMimeData *data = new QMimeData;
data->setProperty("type",property("type"));
QDrag *drag = new QDrag(this);
drag->setMimeData(data);
drag->start();
}
}


//#view.cpp - Wrapper class for QGraphicsView

#include "view.h"

View::View(Scene *scene,QWidget *parent)
:QGraphicsView(scene,parent)
{
}

View::~View()
{
}


//#scene.cpp - Wrapper class for QGraphicsScene which catch drop events

#include "scene.h"

Scene::Scene(QObject *parent)
:QGraphicsScene(parent)
{
}

Scene::~Scene(void)
{
}

void Scene::setSceneRect(qreal x, qreal y, qreal w, qreal h)
{
QGraphicsScene::setSceneRect(x,y,w,h);
}

void Scene::dragEnterEvent(QGraphicsSceneDragDropEvent *e)
{
if(e->mimeData()->hasFormat("text/plain"));
e->acceptProposedAction();
}

void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent *e)
{
}

void Scene::dropEvent(QGraphicsSceneDragDropEvent *e)
{
e->acceptProposedAction();
int itemType = e->mimeData()->property("type").toInt();
switch(itemType)
{
case BlockSegment:
drawStandartBlockSegment(e->scenePos());
break;
case Switch:
drawStandartSwitch(e->scenePos());
break;
case Signal:
drawStandartSignal(e->scenePos());
break;
}
}

void Scene::drawStandartBlockSegment(QPointF p)
{
BlockSegmentItem *blockSegment = new BlockSegmentItem(p.x(),p.y(),p.x()+100,p.y());
addItem(blockSegment);
}

void Scene::drawStandartSwitch(QPointF p)
{
SwitchItem *switchItem = new SwitchItem(":app/SS.svg");
switchItem->setPos(p);
addItem(switchItem);
}

void Scene::drawStandartSignal(QPointF p)
{
SignalItem *signalItem = new SignalItem(":app/sgs3lr.svg");
signalItem->setPos(p);
addItem(signalItem);
}


//#item.cpp - Base class for my custom graphics scene items

#include "item.h"

Item::Item(ItemType itemType, QGraphicsItem *parent)
:QGraphicsWidget(parent),m_type(itemType)
{
}

Item::~Item()
{
}

int Item::type()
{
return m_type;
}

QRectF Item::boundingRect() const
{
return QRectF(0,0,0,0);
}

QPainterPath Item::shape() const
{
QPainterPath path;
return path;
}

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(painter);
Q_UNUSED(option);
Q_UNUSED(widget);
}

void Item::deleteItem()
{

}

void Item::contextMenuEvent(QGraphicsSceneContextMenuEv ent *event)
{
Q_UNUSED(event);
}


//#switchitem.cpp - my custom switch item.

#include "switchitem.h"

SwitchItem::SwitchItem(const QString& fileName,QGraphicsItem *parent /* = 0 */)
:Item(Switch,parent)
{
svg = new QGraphicsSvgItem(fileName,this);
createActions();
createContextMenu();
}

SwitchItem::~SwitchItem(void)
{
}

QRectF SwitchItem::boundingRect() const
{
return QRectF(pos().x(),pos().y(),svg->boundingRect().width(),
svg->boundingRect().height());
}

QPainterPath SwitchItem::shape() const
{
QPainterPath path;
path.addRect(boundingRect());
return path;
}

void SwitchItem::createActions()
{
deleteAct = new QAction("Sil",this);
deleteAct->setIcon(QIcon(":app/delete.png"));
connect(deleteAct,SIGNAL(triggered()),this,SLOT(de leteItem()));
}

void SwitchItem::createContextMenu()
{
contextMenu = new QMenu("SwitchContextMenu");
contextMenu->addAction(deleteAct);
}

void SwitchItem::contextMenuEvent(QGraphicsSceneContext MenuEvent *e)
{
contextMenu->exec(e->screenPos());
}


//#app.cpp - Application class

#include "app.h"
#include "dragwidget.h"

App::App(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
Q_INIT_RESOURCE(app);
ui.setupUi(this);
canvasScene = new Scene(this);
canvasScene->setSceneRect(0,0,5000,5000);
canvasView = new View(canvasScene);
canvasView->setBackgroundBrush(Qt::black);
canvasView->ensureVisible(0,0,canvasView->geometry().width(),canvasView->geometry().height());
QHBoxLayout *layout = new QHBoxLayout;
toolBox = new QFrame(this);
layout->addWidget(toolBox,1);
layout->addWidget(canvasView,7);
ui.centralWidget->setLayout(layout);
createToolBox();

}