[Solved] Are nested event filters allowed/recommended
-
In principle, I think you are right (though your implementation lacks a bit). You could protect your eventFilter implementation by putting the actual event filter in a separate, private object in your class and either handle it there, or defer the handling again to a private method in the widget. Still, you have to ask yourself how useful that is. You run the risk that the user is unaware of the internals of your class not only with the eventFilter method, but with every virtual method in your widget, including those inherited from QObject and QWidget. And those are certainly not the -most- least important ones! When reimplementing a virtual method, you have to know what you're doing, and it often is a great idea to call the base implementation for the cases you don't handle yourself anyway. You have to ask yourself if you really want to try to protect the user of your library from all these possible pitfals?
-
The API docs on "QObject::eventFilter() ":http://doc.qt.nokia.com/stable/qobject.html#eventFilter even mentions this:
bq. Notice in the example above that unhandled events are passed to the base class's eventFilter() function, since the base class might have reimplemented eventFilter() for its own internal purposes.
You can add a prominent message in your API docs to warn your users.
Andre is totally right. It is good practice to call the base class' virtual method unless you really know what you're doing.
If you really want to, you can of course put the event filter in a private object of the parent class. If you do that, then there is no need to define and implement an eventFilter() method in the parent class.
-
Volker, if you read the example code of Dieter, you see:
@
class CInternalFilterObject : public QObject
{
public:
CInternalFilterObject(CObjectToFilter* parent): QObject(parent), itsParent(parent) {}
bool eventFilter(QObject* obj, QEvent* event)
{
return itsParent->event(obj, event);
}private:
CObjectToFilter* itsParent;
}class CObjectToFilter: public QObject
{
CObjectToFilter()
{
installEventFilter(new CInternalFilterObject(this));
}
bool eventFilter(QObject* obj, QEvent* event)
{
// do stuff
return ???;
}
}
@That means, in the class CObjectToFilter, he creates an object to filter the events of CObjectToFilter (CInternalFilterObject), which then calls CObjectToFilter. This is a loop from CObjectToFilter over CInternalFilterObject to CObjectToFilter. That means, it can also be removed and will have the same effect.
-
Thank you for all your valuable input.
-
I must admit that I did not even know of the option to just overload the method QObject::event()
This is an interesting alternative to the use of an event filter and would clearly make my second code snippet simpler. -
For my specific problem I will stick with the good old "call the base class’ virtual method" approach as suggested.
@
bool derivedClass::eventFilter(QObjectobj, QEvent event)
{
if (event->type() == ...)
{
// do stuff ...
return ???;
}
else
{
// if it's not "ours", just pass the event on to our parent class
return parentClass::eventFilter(obj, event);
}
}
@ -
-
[quote author="Dieter" date="1294754903"]
- I must admit that I did not even know of the option to just overload the method QObject::event()
This is an interesting alternative to the use of an event filter and would clearly make my second code snippet simpler.
[/quote]
If you are only interested in some special events, you can also just overwrite the specific event handlers (see "QObject":http://doc.qt.nokia.com/latest/qobject.html#protected-functions and "QWidget":http://doc.qt.nokia.com/latest/qwidget.html#protected-functions documentation).
- I must admit that I did not even know of the option to just overload the method QObject::event()
-
QObject::event() only works for the events that are actually delivered to the QObject where this method is (re)implemented.
QObject::eventFilter() is for one QObject that filters the events of another QObject. Although it can be abused on this object too (thus filtering events on itself), it would definitely be better to reimplement event() (or any of the specialized xyzEvent() methods) in this case! Please do everyone a favor and consider this!
Also, watch out to check the obj pointer in eventFilter()! You should react on the event type and the proper object!
-
Thank you for the additional clarifications!