在C ++ Qt中有一个类QWidget
A
继承了QWidget
并添加了一些功能B
继承了A
并添加了一些功能C
继承B
并添加了一些功能,C
必须是QWidget
类型,并且应该通过B
完成所有工作由于某些原因C
的行为不符合预期,我必须重写类C
。我无法将代码修改为B
类创建。
我该如何解决这个问题?任何设计模式,还是其他什么?
如果我尝试继承多重继承QWidget
和B
,则会有两个QWidget
导致问题(QObject - moc不允许)。
如果我从QWidget
继承并将B
的对象传递给C
的构造函数,那么B
执行的任何操作都适用于另一个QWidget
B
提供的所有功能都应该适用于我的B
C
。
答案 0 :(得分:1)
假设有一个温度传感器,当它与机器断开连接时,类
B
在其拥有的QWidget
的整个区域上绘制内容阻止器图像,我可以监视传感器连接/断开连接假设C
很有趣。OnDisconnect()
被调用,我会调用B::OnDisconnect()
,B
将在自己的QWidget
上绘制阻止图像,而不是C
拥有的图像。< / p>
与C ++相比,这与C ++的相当不灵活的方法实现继承有关。到共同的LISP对象系统。
由于B
的隐藏始终是在B
的内容之上,因此您实际需要的是B
提供叠加层即使在派生类中覆盖paintEvent
,也会在其内容之上绘制。
有关简单示例,请参阅this answer;有关具有模糊图形效果的叠加层,请参阅another answer。
通过B
向自身添加可选的叠加窗口小部件,可以轻松完成此任务。
示例:
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);
...
}
};
如果您没有B
的源代码,则可以将叠加层添加到C
,在隐藏时复制原始B
的功能。 Qt的所有广告位都是虚拟广告,因此如果您将C
传递给期待B
并连接到其OnDisconnect
广告位的用户,则会C
& #39;将被调用的插槽。
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};
...
}
};