QQuickItem overrides and calling base method
-
I am currently re-implementing some code, originally done in QWidgets, in QML. This involved rendering pixmaps using
QWidget::paintEvent
. The code seems to translate over to QML pretty well usingQQuickPaintedItem
.Using the
QQuickItem
API directly is fairly new to me and one thing that threw me was that if I followed what was done too blindly in theQWidget
version with regard to mouse event handling, the QML version was not responding to certain mouse operations. In particular, all of the overrides ofQWidget::mousePressEvent/mouseReleaseEvent/mouseMoveEvent...
end by delegating to the base method:void MyWidget::mousePressEvent(QMouseEvent* evt) { ... // my override stuff QWidget::mousePressEvent(evt); }
When I followed this pattern in the
QQuickPaintedItem
version, I found thatmousePressEvent
was triggered, but notmouseMoveEvent
andmouseReleaseEvent
.Looking in the Qt source, I see that the default
QQuickItem::mousePressEvent
implementation callsignore()
on the event, which (I think) explains what I was seeing. This is not spelled out in the documentation as far as I can see.My question is: as a general rule of thumb, if I override a
QQuickItem
protected method for mouse, key, wheel events, or whatever, do I just ignore the base method, or are there situations where I should call it like I see happening everywhere in theQWidget
code? -
The documentation is wrong.
At a glance, the following QQuickItem event handler implementations are incorrectly documented as accepting the event, because the event is explicitly ignored:
QQuickItem::keyPressEvent
QQuickItem::keyReleaseEvent
QQuickItem::inputMethodEvent
QQuickItem::mousePressEvent
QQuickItem::mouseMoveEvent
QQuickItem::mouseReleaseEvent
QQuickItem::wheelEvent
QQuickItem::touchEventFortunately, none of these do any useful work. Overrides can either not call them, or accept the event after. The documentation usually mentions which base class functions should be called when overridden:
https://doc.qt.io/qt-6/qquickitem.html#focusInEvent
If you do reimplement this function, you should call the base class implementation.
-
@jeremy_k thanks, yes - I think at best the documentation is ambiguous. It says that by default the event is accepted - presumably before the handler is called - so that one does not need to explicitly accept it if the handler is overridden. It doesn't actually say one way or the other what the base implementation does but I think a quick reading of the documentation would give an impression that the event is accepted.
-
@Bob64 said in QQuickItem overrides and calling base method:
It says that by default the event is accepted - presumably before the handler is called - so that one does not need to explicitly accept it if the handler is overridden.
The handlers are ordinary C++ virtual functions, called from QQuickItem::event(). If event() or the relevant *Event() is overridden, it's up to the override to invoke the default behavior. Otherwise, it doesn't happen.
https://codebrowser.dev/qt6/qtdeclarative/src/quick/items/qquickitem.cpp.html#8879
case QEvent::MouseButtonPress: mousePressEvent(static_cast<QMouseEvent*>(ev));
It doesn't actually say one way or the other what the base implementation does but I think a quick reading of the documentation would give an impression that the event is accepted.
Some of the documentation is more thorough, and some of it is in higher level descriptions. QWidget::mousePressEvent, for example:
The default implementation implements the closing of popup widgets when you click outside the window. For other widget types it does nothing.