views:

56

answers:

1

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. alt text 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);
}
+1  A: 
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();
    }
}

Problem is here. You've "eaten" right button :) Try fall back into base implementation of mousePressEvent

Kamil Klimek
I think problem is not related with mouse button. Because I fall back to base implmentation but context menu does not work.
onurozcelik