这是一个SpinBox的示例,它将其更改写入基础变量。构建窗口小部件时,我调用的主要问题是valueChanged。有没有更优雅的方式来做到这一点?我认为将小部件与自身连接起来很奇怪,但valueChanged不是虚拟的。
class ValueWriterInt: public QSpinBox {
Q_OBJECT
public:
ValueWriterInt(vector<int*> const& value): myValue(value) {
QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
}
~ValueWriterInt() {}
private slots:
void valueChanged(int new_value) {
for (auto it = myValue.begin(); it != myValue.end(); ++it)
**it = new_value;
}
private:
vector<int*> myValue;
};
答案 0 :(得分:1)
我认为将小部件连接到自身并不特别奇怪。有一种检测和响应数据更新的方法实际上听起来是件好事,因为您在调试时检查失败的次数较少。在您的具体情况下,它会导致一些不良行为,但一般来说这是一个很好的解决方案。
现在,我已经表达了一种认为反身联系本身并不优雅的观点,我将提出一个不那么“优雅”的解决方案,以防止在施工后调用valueChanged
。您可以使用一个标志来确定对象是否刚刚构造并提前返回以防止代码在构造后立即运行。在您的示例中:
class ValueWriterInt: public QSpinBox {
Q_OBJECT
public:
ValueWriterInt(vector<int*> const& value): myValue(value), myAfterInit(true) {
QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
}
~ValueWriterInt() {}
private slots:
void valueChanged(int new_value) {
if (myAfterInit) {
myAfterInit = false;
return;
}
for (auto it = myValue.begin(); it != myValue.end(); ++it)
**it = new_value;
}
private:
vector<int*> myValue;
boolean myAfterInit;
};
这对解决方案来说并不算太糟糕。它将至少为您提供所需的行为,直到(以及如果)您可以找到更优雅的方法。
答案 1 :(得分:0)
那么你想在这里完成什么?是的,valueChanged不是虚拟的 - 为什么它应该是,你的对象应该直接将他们自己的插槽连接到他们想要响应的任何信号,不是吗?
答案 2 :(得分:0)
除了使用SIGNAL-SLOT连接之外别无他法。但是,我会更改插槽的名称,因此它与信号名称不同。
即使没有完成连接,如何调用插槽也很有趣。我怀疑更改插槽名称可以解决这个问题。