How and why Qt functions can be overridden
corbelligiuseppe at mesdan.it
Mon Aug 30 10:54:51 BST 2021
On 8/29/21 1:31 AM, Maurizio Berti wrote:
> Premise: while I can read and almost always understand C++, I don't
> really know a lot about it.
> Subclassing and overriding of Qt classes is almost natural to me, but I
> still don't understand some aspects about function overriding, since I'm
> too accustomed to the "simpler" way of python subclassing.
> For instance, many widgets have an initStyleOption that cannot be
> overridden (well, it could, but it's never called natively), while a
> similar function can be overridden for QStyledItemDelegate.
> From my limited knowledge I can understand that I can
> override/overwrite a function in a subclass and be sure that it's called
> natively by Qt if it's public or virtual (like the initStyleOption of
> QStyledItemDelegate), but this is still a very "foggy" understanding.
Override is the correct term. Also used as an identifier for virtual
functions in C++11.
Visibility (public/protected) is not relevant in this context. AFAIK sip
4 can be instructed to provide access to protected C++ functions so
these are the kind of members you may override.
For each C++ class sip 4 creates a C++ subclass that will be compiled to
be a part of the Python module. Then you can override any public or
protected member in Python.
Let's use QToolButton as an example.
void QToolButton::initStyleOption(QStyleOptionToolButton *option) const
is the prototype.
It is called in:
QSize QToolButton::sizeHint() const
void QToolButton::paintEvent(QPaintEvent *)
QStyle::SubControl QToolButtonPrivate::newHoverControl(const QPoint &pos)
void QToolButton::mousePressEvent(QMouseEvent *e)
and maybe in other non-overridden methods in base classes.
Given that initStyleOption is NOT virtual and you do not (or cannot)
reimplement all the members where it is called your overridden
implementation is useless.
It is NOT called because each call in C++ code uses the base class as
the method is not virtual.
In other words: when QToolButton::paintEvent() is called (Qt event
delivery, I don't know the inner working) the
QToolButton::initStyleOption() implementation is ALWAYS called as the
C++ code has no way to know that an overridden implementation is
available (method is not virtual so no vtable is generated).
> For example, I can override all QItemDelegate drawing functions, except
> for drawBackground, which is not virtual; this means that if I want to
> implement it (because, for some reason, I don't want to use
> QStyledItemDelegate), I need to completely port its paint method so that
> I can finally call a possibly custom drawBackground.
You would also need to take into account every other place where
drawBackground() is called, possibly in base classes.
> Is it possible to make it virtual? If not (as I believe it is), then why?
No it's not. Or at least not easily as you would need to modify the Qt
> Also, most importantly, why is it not virtual?
Absolutely no idea.
More information about the PyQt