在子类中覆盖基类信号时连接到基类的信号
Connecting to a base class' signal when overriding it in a subclass
Qt提供了QSpinBox
,这是提供信号的远QObject
导数:
class QSpinBox:
public /* ... */ QObject {
signals:
void valueChanged(int i);
};
从这个旋转框派生时,我可能会为此信号提供一个覆盖,以发出该值的一些美化版本:
class MySpinBox:
public QSpinBox {
private slots:
void originalValueChanged(int i) {
/* Beautify */
emit valueChanged( 42 * i );
}
signals:
void valueChanged(int myPersonalI);
};
这似乎很好:信号MySpinBox::valueChanged(int)
隐藏了继承的信号。唯一缺少的一点是将继承的QSpinBox::valueChanged(int)
连接到专用插槽MySpinBox::originalValueChanged(int)
。
虽然使用新信号和时隙语法可以做到这一点:
connect(
static_cast<QSpinBox *>(this), &QSpinBox::valueChanged,
this, &MySpinBox::originalValueChanged);
我既不确定这是否允许或明智,也不确定如何使用传统的基于字符串的信号/插槽语法连接信号。使用后者,插槽显然连接到MySpinBox::originalValueChanged(int)
信号,这显然不是故意的。
目的
上面的例子被简化为我认为我面临的问题。为了理解为什么我会遇到这个问题,也许是为了引导我摆脱这个(假装的(破碎的设计,想想一个QDoubleSpinBox
导数来输入一些物理量,例如速度。用户可能希望以某个首选单位输入此内容,该单位可能是km/h
或mph
。为了从应用程序中获取单位转换逻辑,我编写了一个新的小部件,该小部件派生自QWidget
,仅包含一个QDoubleSpinBox
。然后我实现了通常的旋转盒方法(setMinimum
、setSingleStep
等(,这些方法采用 SI 维度的相应属性(即本例中的 m/s
(,将它们转换为某个选定的单位,然后配置较差的双旋转盒。
setValue(double)
将其参数转换为用户的单位,并将其传递给下级。反过来,有一个valueChanged(double)
信号,每当劣质旋转盒发出valueChanged
,但数量转换回SI维度时就会发出。
所以最后我修修补补的是,不是用劣质的旋转盒来编写QWidget
导数,而是从QDoubleSpinBox
派生并重新实现。
利弊似乎部分清楚,包括下面斯特拉霍夫@Pavel解释的问题。实际上,编写小部件可以让我摆脱错误继承的方法被调用(由于不是虚拟的(,代价是包装QWidget
。因此,作为中间步骤,我正在修补从QDoubleSpinBox
派生私有。这当然不是 GUI 应用程序中的资源问题,但对我来说,这也是学习和修补的问题。
然后我偶然发现了这个信号,想知道Qt会怎么想。
请注意,QSpinBox::valueChanged
不是虚拟的,这意味着如果QSpinBox*
指针中存储了MySpinBox
的实例并调用其 valueChanged
方法,则将执行QSpinBox::valueChanged
而不是MySpinBox::valueChanged
。Qt内部函数肯定会有QSpinBox*
指向实例的指针。这种不一致可能是错误的根源。非虚函数不应该在子类中重新定义,你不应该这样做。Qt内置类都没有使用这样的重新定义。子类通常会添加新信号,而基类信号保持不变。
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 如果基类包含双指针成员,则派生类的构造函数
- 如何在基类中使用来自qt中所有继承类的信号?
- 信号/插槽基类多继承
- 使用派生的类对象 Qt 访问基类信号
- Qt UI 插槽不是由从基类继承的信号调用的
- 在子类中覆盖基类信号时连接到基类的信号
- 将Qt基类信号映射到派生类中的槽
- Qt:如何为所有小部件和小部件类型实现通用基类信号/插槽功能(通过虚拟基类插槽)
- 无法从基类连接信号