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)
。
虽然可以使用 new 信号和插槽语法:
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 Strakhov解释的问题。实际上,编写窗口小部件可以让我摆脱被调用的错误继承的方法(由于不是虚拟的),代价是包装QWidget
。所以作为一个中间步骤,我正在修补从QDoubleSpinBox
派生私人。这肯定不是GUI应用程序中的资源问题,但对我而言,这也是学习和修补的问题。
然后我偶然发现了信号,想知道Qt会怎么想。
答案 0 :(得分:0)
请注意,QSpinBox::valueChanged
不是虚拟的,这意味着,如果MySpinBox
指针中存储了QSpinBox*
的实例并调用其valueChanged
方法,则QSpinBox::valueChanged
将被执行而不是MySpinBox::valueChanged
。 Qt内部函数肯定会有QSpinBox*
指向实例的指针。这种不一致可能是错误的根源。非虚函数不应在子类中重新定义,您不应该这样做。 Qt内置类都没有使用这种重新定义。子类通常会添加新信号,不会触及基类信号。