Signals and slots: mutual connections - How to avoid feedback?



  • Greetings!

    In my application I need a pair of widgets (to specify: dial and spin box) to work in a way, that changing value in one of them will automaticly cause value change in the other one. If I make these connections via Qt Designer (Edit Signals/Slots mode) it works, but unfortunatly I need special handling for values that are going to be set.

    Here are these mutual connection, that I make in a constructor of my widget's class:
    @
    QObject::connect( ui->FreqDial, SIGNAL( valueChanged(int) ),
    this, SLOT( SetFreqSpinBoxValue(int) ) );
    QObject::connect( ui->FreqSpinBox, SIGNAL( valueChanged(int) ),
    this, SLOT( SetFreqDialValue(int) ) );
    @

    And here's code of my functions:
    @
    void GeneratorWindow::SetFreqSpinBoxValue(int value)
    {
    double spinBoxValue = 0;

    /* Calculations... */
    
    ui->FreqSpinBox->setValue( static_cast<int>(spinBoxValue) );
    

    }
    @

    @
    void GeneratorWindow::SetFreqDialValue(int value)
    {
    double dialValue = 0;

    /* Calculations... */
    
    ui->FreqDial->setValue( static_cast<int>(dialValue) );
    

    }
    @

    Of course it generates some kind of feedback - calling one of these functions emits a signal, the other functions is called, it emits it's own signal and that keeps going on forever. My question is how can I prevent that from happening?

    Thank you for your answers,
    Boris



  • You could block signal emission during the manual update.
    @
    void GeneratorWindow::SetFreqSpinBoxValue(int value)
    {
    double spinBoxValue = 0;

    /* Calculations... */
    
    bool signalsBlocked = ui->FreqSpinBox->blockSignals(true);
    ui->FreqSpinBox->setValue( static_cast<int>(spinBoxValue) );
    ui->FreqSpinBox->blockSignals(signalsBlocked);
    

    }
    @



  • What kind of widgets are these two ?? I suppose, both are [[doc: QSpinBox]] . And i suppose there is something else causing the trouble. Because, i have used in criss cross way, and worked fine.



  • Thank you very much, Lukas - it works perfectly :).


  • Moderators

    A good design principal in writing a setter is to make sure that the new value is different than the old value before doing any kind of assignment and signaling...

    @
    void SomeClass::someSetter(int value) {
    if (value != the_current_value)
    {
    the_current_value = value;
    emit theValueChanged(value);
    }
    }
    @

    This will prevent those kind of infinite loops without having to block signals.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.