I have 2 event filters installed on the same object on different levels of inheritance. Some old sources claim that the order in which the filters are applied is the inverse installation order. This only makes sense to me, since specialized behavior of derived classes should generally take precedence to override existing behavior provided by base classes, while initialization, where event filter installation seems best to be done, takes place in the inverse order to this precedence.
But I find this not to be so in my program. When debugging I get the same order for precedence as for installation and also subsequently problems in my code. Since I have an inheritance structure involved, my base class' provided behavior takes precedence over my derived class'. Problems thereby arise, because both filters are supposed to filter the same object and are not commutative, in my case on a wheel scroll, one in the context of base-class behavior, the other in the special case of the derived class towards another use case. The base class' design is supposed to be closed and thereby access to the code where the base class' filter is set, as well as the filter object itself is not granted from derived class' code.
Questions:
Because I got contradicting sources here and I couldn't find anything in documentation:
- How is the precedence supposed to be set by Qt?
To find a solution to this problem going forward:
- How to influence the precedence of filters, or their general ordering?
- How to maybe achieve the same better way?
Exemplary Pseudo-Code:
class FilterX{ void eventFilter() { /* do something general */ } };
class A { FilterX filterx; A() { this->installEventFilter(filterx); } };
class B : public A {}; class C : public B{}
class FilterY{ void eventFilter() { /* do something specialized */ } };
void f()
{
C c;
A* a = &c;
c->installEventFilter(filterY);
// ...
}
//Later on event I get execution order
FilterX::eventFilter()
FilterY::eventFilter()
I currently run QT LTS 5.15
CodePudding user response:
I am pretty sure the documentation is right and you have some error in your code.
Since your code snippet is not correct and contains many many bugs, I cleaned it up and made it runnable.
#include <QCoreApplication>
#include <QDebug>
class FilterX : public QObject
{
bool eventFilter(QObject *, QEvent *) override
{
qInfo() << "event filter X";
return false;
}
};
class A : public QObject
{
FilterX filterx;
public:
A()
{
installEventFilter(&filterx);
}
};
class C : public A {};
class FilterY : public QObject
{
bool eventFilter(QObject *, QEvent *) override
{
qInfo() << "event filter Y";
return false;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
C c;
FilterY filterY;
c.installEventFilter(&filterY);
QEvent event(QEvent::Paint); // just an example of an event
QCoreApplication::sendEvent(&c, &event);
return a.exec();
}
If you run it, the output is:
event filter Y
event filter X
i.e. exactly as expected: the event filters are executed in the reverse order of their installation on the object. Inheritance of hierarchy does not play any role in it.