Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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