PDA

View Full Version : How can both graphicsView and graphicsItem receive mousemoveEvent?



christina123y
15th March 2009, 03:51
Hi, everyone, I have countered a problem : How can both graphcisView and graphicsItem
receive mousemoveEvent?
Because I have carried out that the graphicsView to track mouse move postion, througth QGraphcisView::mouseMoveEvent(QMouseEvent * event);

And I also carried out that the graphcisItem to zoom out the graph by choose a rubberband rect, through QGraphicsItem::mousePressEvent(QGraphicsSceneMouse Event *event) ,QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouse Event *event),
QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMou seEvent *event) .This can be realized only when i remove the QGraphcisView::mouseMoveEvent(QMouseEvent * event) in the QGraphicsView class.

Last I found that ,if i don't remove the QGraphcisView::mouseMoveEvent(QMouseEvent * event) in the QGraphicsView class,then the graph can realize the mouse position tracking,which means that the QGraphicsView class has grab the mouseMove event, and then i press the button and try to select a rubberband rect ,then it doesn't succeed!

Now i both need the mouse tracking and rubberband zoom . how can both the QGraphicsView class and QGraphcisItem class receive mousemove event ?

Wish anyone's preciously adivce! Thank you!

wysota
15th March 2009, 08:01
If you ignore() the event in the item, it will propagate to other items and then to the scene and then to the view. Another solution is to install an event filter on the item - then the scene will get the event before the item does.

christina123y
15th March 2009, 08:52
If you ignore() the event in the item, it will propagate to other items and then to the scene and then to the view. Another solution is to install an event filter on the item - then the scene will get the event before the item does.

hi, wysota,Thank you very much!
i want to tell you that I haven't use any ignore() in my item class before.

I know what you mean. now my thought is : First, if i don't press mouse left button, then the mouseMoveEvent must be passed to qGraphicsView class, if i press mouse left button,
i should pass the mousemoveevent to the qgraphicsItem class. And should i install an event filter on the qGraphicsItem class or on the qGraphicsView class?
And how to do this?

Wish you reply again! Thank you!

aamer4yu
15th March 2009, 10:28
By the way, what do you want to achieve using the mouse events ?
It could be more help if we understand what you are trying to do

christina123y
15th March 2009, 12:42
By the way, what do you want to achieve using the mouse events ?
It could be more help if we understand what you are trying to do

I use mouse events for two reasons, first i want to achieve mouse position tracking,which has been successfully achieved while mouse move, i reimplement mouseMoveEvent(QMouseEvent *event) in the class which inherits from QGraphicsView, and last get the mouse postion when mouse move.
secondly, i want to achieve zoom in the graph (which is drawed in a class inherits from QGraphicsItem) by choose a rubberband rect. and I reimplement QGraphicsItem::mousePressEvent(QGraphicsSceneMouse Event *event),
QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseE vent *event),
and QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMou seEvent *event) in the item class, i achieve this function only when i remove mouseMoveEvent(QMouseEvent *event) in the class which inherit from QGraphicsView.
If i don't remove mouseMoveEvent(QMouseEvent *event) in the class which inherit from QGraphicsView, when i press mouse left button to select a rubberband rect, there will be a line in the graph not a rubberband rect, and the graph doesn't have been zoomed. I think that the class inherit from QGraphicsView has intercepted the mouseEvent .

However , i want to achieve both the mouse position tracking and zoom in graph through select a rubberband rect. I want to ask how can i both realize these two function . so i think the main problem i have to resolve is that when i don't press mouse left button, the class inherit from QGraphicsView can grab mouse move event to achieve mouse position, and when i press mouse left button, the class inherit from QGraphicsItem can grab the mouse move event in order to form a rubberband rect.
i want to ask how can i to do this?

In my source, i define two class respectively inherits from QGraphicsView and QGraphicsItem!

Sorry, i wish now i have delivered myself. And thank you for your help.
wish your answer soonly! Thank you!

aamer4yu
15th March 2009, 12:53
In short what I understand is you want to zoom into the scene / view with rubberband effect.

I dont think you have to go to items level for that. What you need to do is - catch mouse events in your scene / view. Draw the rubberband in mouse move events, and finally on mouse release event you capture a rect, from the mousepress(x,y) and mouserelease(x,y).
Now you convert this rect in to scene rect, and call QGraphicsView::fitInView()

Thats it, you are zoomed in :-) , and you only had to capture events in the view ;)

christina123y
15th March 2009, 13:56
In short what I understand is you want to zoom into the scene / view with rubberband effect.

I dont think you have to go to items level for that. What you need to do is - catch mouse events in your scene / view. Draw the rubberband in mouse move events, and finally on mouse release event you capture a rect, from the mousepress(x,y) and mouserelease(x,y).
Now you convert this rect in to scene rect, and call QGraphicsView::fitInView()

Thats it, you are zoomed in :-) , and you only had to capture events in the view ;)


hn, by now,i achieve my zoom in by select rubberband rect in the items level. and achieve mouse tracking in the qgraphicsview level. how can i the item receive mousepress ,mousemove,mouserelease event which will not be intercepted by the qgraphicsview?
I have looked up lots of eventfilter,but haven't been succeeded now.

aamer4yu
15th March 2009, 16:24
What do you want to do with the items ? am not clear what you want to do with items WHILE you are rubberbanding ?

By the way did you have a look at the 40000 chips demo in Qt Demos ? It also has rubberbanding.

wysota
15th March 2009, 16:52
Have you seen QGraphicsView::dragMode ?

lni
15th March 2009, 18:41
What do you want to do with the items ? am not clear what you want to do with items WHILE you are rubberbanding ?

By the way did you have a look at the 40000 chips demo in Qt Demos ? It also has rubberbanding.

There may be many reasons to select an item, let's say I want to edit the pen color by double click on the item and pop up a pen editor...

Someday I will need that too when I get to that point...

christina123y
16th March 2009, 01:55
Have you seen QGraphicsView::dragMode ?

I have looked up QGraphicsView::dragMode in the QT assitant.But i don't know how this can help me? I have written eventfilter in the QGraphicsItem class,but it does nothing. There still only mouse move position tracking,but can't draw a rubberband rect,not less than zoom in through select a rubberband rect

aamer4yu
16th March 2009, 04:39
There may be many reasons to select an item, let's say I want to edit the pen color by double click on the item and pop up a pen editor...

Someday I will need that too when I get to that point...
You didnt pay to the WHILE part... am not clear what you want to do with items WHILE you are rubberbanding ?

christina123y
16th March 2009, 08:49
You didnt pay to the WHILE part... am not clear what you want to do with items WHILE you are rubberbanding ?

You still didn't catch what i mean. I mean that ,only when i remove the mouseMoveEvent(QMouseEvent *event) function in the class which inherit from QGraphicsView , then the rubberbandrect can be achieved.(The rubberband rect function was achieved through the way :reimplement mousePressEvent, mouseMoveEvent , mouseReleaseEvent function in the class which inherit from QGraphicsItem).
If i don't remove the mousemoveEvent function in the class which inherit from QGraphicsView, then the rubberbandrect can't be achieved. Now i think the main reason is that the class which inherit from QGraphicsView has intercepted the mouse event before the class which inherit from the item.

wysota
16th March 2009, 09:55
I have looked up QGraphicsView::dragMode in the QT assitant.But i don't know how this can help me? I have written eventfilter in the QGraphicsItem class,but it does nothing. There still only mouse move position tracking,but can't draw a rubberband rect,not less than zoom in through select a rubberband rect

It can handle rubberband selecting for you. No need to write a single line of code besides activating the proper drag mode.

olidem
16th March 2009, 13:20
Please note the following:
A MouseEvent propagates at first to the item under the mouse.

If you subclass the item and call QGraphicsItem::mouseXXXEvent(envent), it will be propagated further. If you don't do that, the event is seen as processed and "dies".
But if you call the parent handler, then you will meet this event also in the scene and the view again.

Regards,
Olli

aamer4yu
16th March 2009, 14:54
Did you have a look at the example in Qt Demo ?
You can refer it from here (http://doc.trolltech.com/4.5/demos-chip.html)also .
You can select items through rubberbanding. Look into the code how they did it.

christina123y
17th March 2009, 02:47
Please note the following:
A MouseEvent propagates at first to the item under the mouse.

If you subclass the item and call QGraphicsItem::mouseXXXEvent(envent), it will be propagated further. If you don't do that, the event is seen as processed and "dies".
But if you call the parent handler, then you will meet this event also in the scene and the view again.

Regards,
Olli

Oh, thank you very much!
I think this will help me! because i didn't call QGraphicsItem::mouseXXXEvent(envent), so maybe the event is seen as processed and "dies",but i tried this ,but the rubberband rect hadn't been drawn and nothing do to the graph, except the mouse postion tracking .

i will try again!
And now i have remove all mousePressEvent,mouseMoveEvent,mouseReleaseEvent in the class which inherit from the QGraphicsItem.
Then i write the code of zoom in through select a rubberband rect in the class which inherit from the QGraphicsView.At last ,the mouse postion tracking didn't colides with the selection of rubberband rect. and this resolve my problem.
As aamer4yu's reply of #6, he said that
"I dont think you have to go to items level for that. What you need to do is - catch mouse events in your scene / view. Draw the rubberband in mouse move events, and finally on mouse release event you capture a rect, from the mousepress(x,y) and mouserelease(x,y).
Now you convert this rect in to scene rect, and call QGraphicsView::fitInView()
Thats it, you are zoomed in :-) , and you only had to capture events in the view "

He was right, i needn't have to go to the items level. both mouse position tracking and rubberband rect zoom can both be handed in the QGraphicsView level.

but i still puzzled why the view class intercepted the mouse event before the item ?

olidem
17th March 2009, 08:24
but i still puzzled why the view class intercepted the mouse event before the item ?

Because the item "lets them through" ? As long as you call QGraphicsItem::mouseXXXEvent, it will travel through, I think

christina123y
18th March 2009, 01:09
Because the item "lets them through" ? As long as you call QGraphicsItem::mouseXXXEvent, it will travel through, I think

Now i counter another problem, the class which inherit from QGraphicsItem can't be moved and seletable.
and i have setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable)
in it's constructor,but it still can move.(i also try to put setFlags of this item in any possible postion, but it still can't be moved)
but i also add a ellipse item in the scene, howerver,the ellipse item can move.

Why? I don't understand why this happen to this item?
Wish anyone's help soonly !Thank you!

aamer4yu
18th March 2009, 04:16
Are you overriding some events of the item you inherited from graphicsitem ?

If yes, are you calling the base class QGraphicsItem methods from there ?

Sergio
20th March 2009, 15:05
In short what I understand is you want to zoom into the scene / view with rubberband effect.

I dont think you have to go to items level for that. What you need to do is - catch mouse events in your scene / view. Draw the rubberband in mouse move events, and finally on mouse release event you capture a rect, from the mousepress(x,y) and mouserelease(x,y).
Now you convert this rect in to scene rect, and call QGraphicsView::fitInView()

Thats it, you are zoomed in :-) , and you only had to capture events in the view ;)

That is exactly what I need! I've implemented almost all of it, but it is not working when i subclass a scene, and subclass the GraphicsView will be sort of problematic, because I'm using the widget from the Designer widget bar. I would have to create dynamically including the layouts

Thanks in advance for any Help
SC

zgulser
3rd April 2009, 12:22
Hi,

I have very similar problem regarding this subject.

I have a QGraphicsView and QGraphicsScene and some QGraphicsItem (as usual). For again to zoom upan a rubberband action I needed to reimplement mouse move event in QGraphicsView. Moreover, I also want to change the color of the item whenever mouse moves on the item. So it seemed I need to reimplement the mouse move event also in the QGraphicsItem. But I doesn't work. I also tried out eventFilter thing.

Can anyone help me?

Thanks in advance.