PDA

View Full Version : Advice catching dropEvent



DirtyBrush
13th July 2009, 14:32
Hello All,

I have a QGraphicsItem in a QGraphicsScene shown in a QGraphicsView.

Sometimes I want to catch drops with nothing underneath.

Sometimes I want to catch drops within items under the mouse.

Sometimes I want to catch drops within the children items of items under the mouse.

I created my own dropEvent() method in the view, using QDropEvent with this I
can add a new item to the scene.

However, I've got a dropEvent() in my item which uses QGraphicsSceneDragDropEvent
so I cant just call the item's dropEvent method from the view method. I get a type
mis match error.

So far, my hacky work round, is to make my own method myDropEvent in the item
and call this from the view. I'm sure there is a neater way to do this, any
advice?

thanks!

DB

wysota
14th July 2009, 08:42
If you need any special tricks then it means you did something wrong. You should be able to catch the event in the item, the scene or the view just like that. Remember to call the base class implementation of the event if you want it to continue propagation - maybe that's what you are missing.

DirtyBrush
14th July 2009, 11:58
Thanks for the reply.

I'm a bit new to C++, base class implementation... um is that the single
colon thing after the method name? :-)

So when I have -

void myView::dropEvent(QDropEvent *event)
{ ...

I should have -

void myView::dropEvent(QDropEvent *event):dropEvent(event)
{ ...

So this will pass all events onto the scene and then the items? I was a bit
confused with the wording of ignore() and accept() calls for an event.

If I call
ignore() of the event, will it propogate down to the items?

Also, why would I call accept()? If I'm already in the view handler then I'm
already processing it, and by implication accepted?

Thanks again for your response,

DB

DirtyBrush
14th July 2009, 16:19
Hello again,

Some more info...

The ':basemethod(param)' is only for constructors.

I tried

QGraphicsView::dropEvent(event);

In my view code, but didn't get this in the item.

Tried setting the item focus before this as one bit of documentation said
if the item was not in focus event would be ignored.

Tried various combinations of ignore() and accept(), still nothing passed
through to the item.

Do I need to create my own scene class which captures the dropEvent too?
And use my scene dropEvent to pass the event onto the item in the scene?

DB

DirtyBrush
15th July 2009, 14:25
So a different approach, I've removed the DnD overloading from
my version of the QGraphicsView and created my own QGraphicsScene.
I see the dragEnterEvent but not the dropEvent.

Pleeeeeeease, any ideas where I'm going wrong?


myScene::myScene(QObject*parent): QGraphicsScene(parent)
{

}

void myScene::dropEvent(QGraphicsSceneDragDropEvent * event)
{
qDebug() << "Scene sees drop";
}

void myScene::dragEnterEvent(QGraphicsSceneDragDropEven t * event)
{
//event->setAccepted(true);
event->acceptProposedAction();
qDebug() << "scene drag enter";
QGraphicsScene::dragEnterEvent(event);
}

DirtyBrush
15th July 2009, 16:43
Hello Again,

So with a subclass of QGraphicsView and of QGraphicsScene and of QGraphicsItem
I can use the view to create a new item when there is nothing under the mouse
in the scene. Then when there is an item, the scene now gets the dropEvent
and the scene can see that there is an item under the mouse.

However, the item doesn't get the event. Do I need to explicitly tell the scene to
give the event to the item, or some other magic?


void myScene::dropEvent(QGraphicsSceneDragDropEvent * event)
{
qDebug() << "Scene sees drop";
//event->ignore();
//event->accept();
//event->acceptProposedAction();

QGraphicsItem *gi;

gi = this->itemAt( event->scenePos() );

if (gi)
{
qDebug() << "Scene; there is an item thar";
// but item never gets the event :-(
gi->setFocus(Qt::NoFocusReason);
gi->setSelected(true);
//gi->setAcceptDrops(true);
}

QGraphicsScene::dropEvent(event);
}