PDA

View Full Version : installEventFilter trouble



tescrin
9th August 2012, 23:34
Hey there, I'm working on getting an event filter to work. It's supposed to capture all mouse events and then route them to all of it's children. I figured an efficient way to do this was to install an eventfilter which is coded like so:


bool UIEventFilter::eventFilter(QObject *obj,QEvent *e)
{
//capture all mouse events
if(e->type() >= 2 && e->type() <= 5)
{
QList<QObject*> list(obj->children()); //get list of children
int lsize = list.size(); //list size...
for(int i=0;i<lsize;i++) //for each child
list[i]->event(e); //hand it a copy of the event

return true;
}
return false;
}


The problem is, it seems to only hand of mouseReleaseEvent()s. it *might* be handing off mouse-presses, but it's definitely not handing off mouse-move events.

If you can tell why I'd be quite appreciative if you let me know :)

tescrin
10th August 2012, 17:08
They might all be working; I'm getting myriad strange behaviors..


Here's the problem that I have:
-I have a widget that's similar to a dialog (in that it can rest over other widgets)
-It uses a translucent background
-If I use QDialog properties (via set window flags) the clicks that go to the translucent part of the widget pass through as a user (or I) would expect them to. This is important be cause this *can* rest over other widgets. The problem with QDialog properties is getting this widget to move with the window is a pain.
-If I used QWidget properties then the object moves with the window but the translucent portion absorbs clicks

I wanted to be lazy about dealing with moving the widgets around together, so I went the QWidget direction assuming i'd be able to pass my clicks/mousemoves/releases through the first widget via a filter. This has not been successful. I'm looking into the properties of QDialogs and QWidgets to figure out the differences so I can make maybe a hybrid of their properties, but that's the best idea I have at the moment.


EDIT:
Maybe using a mask of the widget (since it has a transparent/nonexistent background) would produce an alpha I could use to ignore mouse signals..

d_stranz
12th August 2012, 02:16
What you are trying to do doesn't make any sense. Suppose the widget that has the event filter installed has 3 QPushButton children. Routing the mouse press event to *all* of them would essentially push all three buttons simultaneously. That can't be the behavior you want.

tescrin
13th August 2012, 15:55
The buttons would receive "pressed" and then I have a function call their "hitbutton" to see which is pressed. This is more for testing so I can get the event filter working. The problem I'm having is that even when I installed an event filter that should block *every* event (a simple "returns false" event filter) it would allow mouseReleaseEvents through. I can tell because it calls my button-menu's menu up which is only called on mouse-release.

I have effects that occur on any given button when it is pressed successfully (again, it'll call qpushbutton::hitbutton before being "successful") and these events never occur, only the mouse-release events. I'm unsure why these would make it through a filter but nothing else.

I know it seems odd, but I was trying to see if it was at least passing the events somewhere.


New question:
Do objects "eat" events at all? Could an event be processed, be "accepted" (or rejected) and then have later objects not react to it?

d_stranz
13th August 2012, 17:23
Do objects "eat" events at all? Could an event be processed, be "accepted" (or rejected) and then have later objects not react to it?

Yes. From the docs:


A mouse event contains a special accept flag that indicates whether the receiver wants the event. You should call ignore() if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it.

and


The QObject::installEventFilter() function enables this by setting up an event filter, causing a nominated filter object to receive the events for a target object in its QObject::eventFilter() function. An event filter gets to process events before the target object does, allowing it to inspect and discard the events as required. An existing event filter can be removed using the QObject::removeEventFilter() function.

When the filter object's eventFilter() implementation is called, it can accept or reject the event, and allow or deny further processing of the event. If all the event filters allow further processing of an event (by each returning false), the event is sent to the target object itself. If one of them stops processing (by returning true), the target and any later event filters do not get to see the event at all.

tescrin
13th August 2012, 18:38
I understand that the *custom* event filters can "eat" events if you want them to; I meant do objects eat events in the standard implementation. I.E. I pass an event to my "Background" object and one of it's buttons uses it; does the button then say "hey I accepted, we're all done!" and then fail to give me back my event for further processing?

Were I to set the value to "rejected" each time, could I pass the same event to several objects? (I've already tried this with qevent::setAccepted(true) thinking I could tell each one that it should accept the event.)

In the end, yes. I'm attempting to get two objects to accept the same event (because one object can accidentally block the event of another; by passing the event to both of them, they can both allow their buttons to check whether they got hit, regardless of how the widget's position interferes.

I originally considered my problem to be that the top level widget was eating the event and thus I wanted an event filter to make the duplicate. (I'm unsure if the button will check if widgets are above it before it accepts the event when I hand it an event directly.) Some of the options Qt gives as standard are so close to what I need but miss something crucial. Setting the Qt::WA_TransparentToMouseClicks would be perfect if it didn't apply to all of the buttons on the dialog it's set to. Anyway...

d_stranz
13th August 2012, 21:04
I think in the case of QInputEvent-type events, if a child widget handles it, it does not get passed up the line to the parent. You could easily check this by making an ordinary dialog, putting a custom button derived from QPushButton on it, and implementing the mousePressedEvent for both widgets. See which one fires when you click on the button and on the dialog itself. I am betting that if you click on the button, the dialog never sees the event.