PDA

View Full Version : wheelEvent not working in an eventFilter



Cruz
31st January 2009, 14:01
Hello,

I'm trying to intercept wheel events in an event filter and it's not working. Here is the filter:



bool KeyframeArea::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *> (event);
mousePressEvent(mouseEvent);
return true;
}
else if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *> (event);
mouseReleaseEvent(mouseEvent);
return true;
}
else if (event->type() == QEvent::Wheel)
{
QWheelEvent *wheelEvent = static_cast<QWheelEvent *> (event);
wheelEvent(wheelEvent);
return true;
}

// Continue standard event processing.
return QObject::eventFilter(obj, event);
}


The filter works for button press and release. For the wheelEvent call I get the error message: `wheelEvent' cannot be used as a function. What's wrong with this? QWheelEvent is included and void wheelEvent(QWheelEvent* event) is declared.

wysota
31st January 2009, 14:40
The function doesn't really make sense. There is no point in calling event handlers manually from within the event filter, especially if you don't know the object they are for...

Anyway your problem is caused by the fact that you named a variable (wheelEvent) the same as a method of the class. Rename it to something else and the problem will go away.

Cruz
31st January 2009, 17:19
Thanks, now I feel really stupid.

As to if it makes sense or not:

I have a number of widgets contained in a bigger widget, let's call it a container. The container provides a rubber band functionality to select one or more of the contained widgets. To make the rubber band work right I filter the mouse events that occur on the children otherwise I would not get them at all. And when I filter them, I call the event handlers of the container, as if the mouse clicks occured on the container directly. How does that not make sense?

wysota
31st January 2009, 18:11
The coordinates carried with the events are mapped to the children coordinate space, not their parent's. You should either do the mapping yourself in the event filter or forward the events to methods different than the original event handlers for the parent.

Anyway, the proper way to do it would be to ignore the events in the children so that they are forwarded to the parent and caught there. Looks like you are trying to emulate this behaviour when it's not required, especially that events get ignored by default if there is no event handler for them implemented and propagated to the parent.

Cruz
31st January 2009, 19:01
The coordinates carried with the events are mapped to the children coordinate space, not their parent's.

Yap. That's why I handle all event coordinates with:


mapFromGlobal(event->globalPos());



...especially that events get ignored by default if there is no event handler for them implemented and propagated to the parent.

Yes that would be the most clean solution, but actually it's like this. The little widgets inside the container are showing 3D views of a skeleton.

- If you left click and drag on the skeleton, it's being rotated, so that you can see it from different perspectives. This operation is clearly assigned to the little widgets.

- If you left click and drag on somewhere else but the skeleton, the widget is being dragged into a drag and drop operation along with all little widgets, that are currently selected. This is a container operation, since the little widget should have no clue about other widgets in the container.

- Is it the right button that you click and drag, then you are opening a rubber band and will select one or more little widgets in the container. Again a container operation.

- If you rotate the wheel on a 3D view, you zoom in and out in the 3D view. A little widget operation.

- If you rotate the wheel somewhere in the container area, you scroll the scroll bar. A container operation.

- If you CTRL-rotate the wheel, then you zoom in and out the whole container, so that all little widgets are resized. A container operation.

The same event (e.g. MouseButtonPress) is handled on a different level depending on if it's a left click or a right click. Do you have a better suggestion, than the event filter method?

And in any case, I would like to maintain the independence of the little widgets from the container. They should not know what container they are in and they should certainly not know about other little widgets in the container. Purposefully ignoring events to pass them on to the container is a bit too specific for my taste. It would make the widgets less reusable in different kind of containers. Then I would rather stick with event filter, so that only the container is ugly.

wysota
31st January 2009, 20:48
Hmm... Have you thought of using QGraphicsView architecture instead of a series of widgets?

Cruz
31st January 2009, 21:41
No, unfortunately that alternative didn't occur to me until you pointed it out just now. It sounds like a very suitable environment for what I'm doing. I have implemented a lot of functionality in the past two weeks and switching to QGraphicsView now would basicly mean redoing everything from the start and finding solutions for all the little problems again that reappear in new forms. I'm certainly not the kind of guy who holds on to the crap he has made in the past if there is a much nicer solution. But I also don't get paid to play around. I have to spend some time thinking my way through it and try to estimate how much time the refactoring would take...and how I can do it secretly of course, because no boss would ever allow this. :)

wysota
31st January 2009, 23:06
No, unfortunately that alternative didn't occur to me until you pointed it out just now. It sounds like a very suitable environment for what I'm doing. I have implemented a lot of functionality in the past two weeks and switching to QGraphicsView now would basicly mean redoing everything from the start and finding solutions for all the little problems again that reappear in new forms.
Maybe it won't be that bad, I'm sure you can reuse some of the code and we will certainly try to help with all the problems that might occur.


and how I can do it secretly of course, because no boss would ever allow this. :)

Errare humanum est... There is really nothing wrong in making a mistake if you learn from it. It's better to correct your errors as early as possible, this costs less than having to go through it anyway at some later point.