Use of QSpinBox::blockSignals. How to avoid infinite loop with valueChanged.
-
I leave this in case someone finds this useful.
Let's say I have a spinBox which is able to set directly an image displayed on a QLabel with
valueChanged
* signal. The same spinBox is updated ( -> it emitsvalueChanged
again ) every time the image is changed from a pushButton with::setValue(int)
** member function.- One way to alter this spinBox, is to interact directly it's arrows to control the image through
image_update
//In the ctor of QtDice connect(m_ui->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, static_cast<void (QtDice::*)(int)>(&QtDice::reload)); //reload calls image_update
- In here the spinBox is just updated with
image_number
; no direct user interaction
//In a member function of QtDice ( void image_update(int) ) m_ui->spinBox->setValue(image_number); //This triggers valueChanged signal leading valueChanged to call this again...
As I noticed each time the spinBox was altered, the
image_update(int)
was called and each timeimage_update(int)
was called the spinBox was altered leading the program in an endless loop. So I had to found a way to instruct the spinBox to emitvalueChanged
only if direct user interaction with it took place.But how do you instruct a spinBox to emit (kind of) conditionally ? As Chernobyl of StackOverflow pointed out, that's the way to go :
.... m_ui->spinBox->blockSignals(true); //Shush, block your signals m_ui->spinBox->setValue(image_number); m_ui->spinBox->blockSignals(false); //OK, emit from now on ...
That's all, I hope this will be useful to someone one day. Of course other more experienced users may add their their solutions.
- One way to alter this spinBox, is to interact directly it's arrows to control the image through
-
Hi,
To avoid signals storms you usually have something like this workflow:
void setMyProperty(int value) { if (value == _myPropertyValue) { return; } _myPropertyValue = value; emit myPropertyChanged(value); }
-
Doing so ensure the proper behaviour. If you connect anything that doesn't do it, you'll still avoid the signal storm.