Suppose there is a temperature sensor, when that gets disconnected from machine, class B draws a content blocker image on the whole area of QWidget that it owns, I can monitor sensor connect /disconnect and suppose C's fun. OnDisconnect() gets called, I will call B::OnDisconnect(), B will draw blocker image on its own QWidget, not on the one which is owned by C.
This has everything to do with C++'s rather inflexible method implementation inheritance when compared e.g. to the Common LISP Object System.
Since B's obscuration is always meant to be on top of B's contents, what you effectively need is for B to provide an overlay that draws on top of its contents, even if paintEvent is overriden in derived classes.
See this answer for a simple example, or another answer for an overlay with blur graphical effect.
This is fairly easy to accomplish by having B add an optional overlay widget to itself.
Example:
class OverlayWidget; // from https://stackoverflow.com/a/19367454/1329652
class ObscureOverlay : public OverlayWidget
{
public:
ObscureOverlay(QWidget * parent = {}) : OverlayWidget{parent} {}
protected:
void paintEvent(QPaintEvent *) override {
QPainter p{this};
p.fillRect(rect(), {Qt::black});
}
};
class A : public QWidget {
...
protected:
void paintEvent(QPaintEvent *) override { ... }
};
class B : public A {
...
ObscureOverlay m_obscure{this};
public:
B() {
m_obscure.hide();
}
Q_SLOT void OnDisconnect() {
m_obscure.show();
...
}
};
class C : public B {
...
protected:
void paintEvent(QPaintEvent * event) override {
B::paintEvent(event);
...
}
};
If you don't have the source code to B, you can add the overlay to C, replicating original B's functionality when obscured. All of Qt's slots are effectively virtual, so if you pass a C to someone expecting B and connecting to its OnDisconnect slot, it will be C's slot that will get invoked.
class C : public B {
Q_OBJECT
...
ObscureOverlay m_obscure{this};
public:
explicit C(QWidget * parent = {}) : B{parent} {
m_obscure.hide();
}
Q_SLOT void OnDisconnect() { // slots are effectively virtual
m_obscure.show();
B::OnDisconnect();
}
protected:
void paintEvent(QPaintEvent * event) override {
B::paintEvent(event);
QPainter p{this};
...
}
};