Mouse wheel events, event filters, and QScrollArea
Let’s say you have a QScrollArea
which contains some custom widget. Now, although this widget itself has no use for mouse wheel events, when it’s in your QScrollArea
you’d really like for it to grow and shrink in response to the wheel. Or maybe you’d just like to map vertical wheel events to horizontal scrolling, since you know the widget will never need vertical scrollbars.
The biggest problem here is that QScrollArea
accepts wheel events (this isn’t strictly true, as you’ll soon see). Events propagate from the child up to the parent until someone accepts the event, and this means that QScrollArea
will prevent wheel events from getting to your own code (again, this isn’t strictly true).
Reading the documentation it’s clear that you’d either want to subclass QScrollArea
or use event filters. Since you don’t need to subclass QScrollArea
for any other reason, using event filters sounds like a reasonable approach. You’ll set up an event filter that forces wheel events to be ignored and install it on the QScrollArea
. That way, it’ll propagate up to your containing widget.
So you’d adjust your containing widget like so:
class MyWidget : public QObject { public: // ... bool eventFilter(QObject* /*obj*/, QEvent* evt) { if (evt->type() == QEvent::Wheel) { // ignore the event (this effectively // makes it "skip" one object) evt->ignore(); } // return false to continue event propagation // for all events return false; } protected: void wheelEvent(QWheelEvent* event) { // your own custom stuff // ... // if you handle the event and don't want it to // propagate any further, accept it: event->accept(); } };
And then you’d use it like so:
QScrollArea* scrollArea = new QScrollArea(parent); scrollArea->setWidget(someWidget); // assuming that 'this' is MyWidget scrollArea->installEventFilter(this);
This doesn’t work. Instead, what you need to do is installEventFilter()
on QScrollArea
’s viewport:
scrollArea->viewport()->installEventFilter(this);
In fact, QScrollArea
is not the one that is accepting wheel events. It’s the viewport that is doing all of that. By installing an event filter on the viewport, the wheel events will continue to propagate up the tree.