In qt, how to implement a widget that is consistent with variables in the code
Here's a sample SpinBox that writes its changes to base variables. The main problem I am facing is valueChanged is called when the widget is built. Is there a more elegant way to do this? It seems strange to me that I have connected the widget to myself, but valueChanged is not virtual.
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;
};
source to share
I don't see anything particularly strange about connecting the widget to myself. Having a uniform method of detecting and responding to data updates actually sounds like a good thing because you have fewer validation problems when debugging. In your particular case, this is causing some unwanted behavior, but overall it is a fine solution.
Now that I have expressed the opinion that reflexive join is not inherently inelegant, I am going to propose a less "elegant" solution for preventing valueChanged
post-build invocation . You can have a flag to determine if an object was just constructed and return early to prevent code from running immediately after it is built. In your example:
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;
};
It's not too bad for a solution. It will at least give you the behavior you want, until (and if) you find a more elegant method.
source to share
I see no other alternative than using SIGNAL-SLOT connections. However, I would change the name of the slot, so it doesn't have the same name as the signal.
It's intriguing how the slot is called, even if the connection hasn't been made yet. I suspect changing the slot name will fix this problem.
source to share