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.
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(QGraphicsSceneContextMenuEvent *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(deleteItem()));
}
void SwitchItem::createContextMenu()
{
contextMenu = new QMenu("SwitchContextMenu");
contextMenu->addAction(deleteAct);
}
void SwitchItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *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();
}
App::~App()
{
}
void App::createToolBox()
{
QVBoxLayout *layout = new QVBoxLayout;
QLabel *blockSegmentLabel = new QLabel("Block Segment");
DragWidget *blockSegmentWidget = new DragWidget;
blockSegmentWidget->setProperty("type",BlockSegment);
blockSegmentWidget->setPixmap(QPixmap(":app/blocksegment.png"));
QLabel *switchLabel = new QLabel("Switch");
DragWidget *switchWidget = new DragWidget;
switchWidget->setProperty("type",Switch);
switchWidget->setPixmap(QPixmap(":app/SS.png"));
QLabel *signalLabel = new QLabel("Signal");
DragWidget *signalWidget = new DragWidget;
signalWidget->setProperty("type",Signal);
signalWidget->setPixmap(QPixmap(":app/sgs3lr.png"));
layout->addWidget(blockSegmentLabel);
layout->addWidget(blockSegmentWidget);
layout->addWidget(switchLabel);
layout->addWidget(switchWidget);
layout->addWidget(signalLabel);
layout->addWidget(signalWidget);
toolBox->setLayout(layout);
}