15

I want to update a widget's value but in order to prevent infinite loops, I need to prevent calling the callback function of this widget's .valueChanged signal.

Following example works entirely as expected:

Qt = PySide

class MainWindow(Actor, Qt.QtGui.QMainWindow):
    def __init__(self):
        Qt.QtGui.QMainWindow.__init__(self)
        Actor.__init__(self)
        self.ui = Qt.loadUI('simulator.ui')
        self.ui.horizontalSlider.valueChanged.connect(self.emit_weight_msg)

    def emit_weight_msg(self, value):
        self.send({'WeightMessage': {'val': value}})

    def handle_WeightMessage(self, msg):
        self.ui.horizontalSlider.valueChanged.disconnect(self.emit_weight_msg)
        self.ui.horizontalSlider.setValue(msg["val"])
        self.ui.horizontalSlider.valueChanged.connect(self.emit_weight_msg)

Since disconnecting and connecting back the valueChanged signals seems a bit like hack, I want to ask if there is a more elegant solution exists.

Full code is here: https://github.com/ceremcem/weighing-machine-testing

Edit

I'm looking for a method, like:

def setValueSilent(QtObject, value):
    tmp_callback = QtObject.get_callback_functions_that_are_set_in_python_code()
    QtObject.valueChanged.disconnect(tmp_callback)
    QtObject.setValue(value)
    QtObject.valueChanged.connect(tmp_callback)
ceremcem
  • 3,900
  • 4
  • 28
  • 66

1 Answers1

26

I think if you use blocksignals then it should be fine.

def handle_WeightMessage(self, msg):
    self.ui.horizontalSlider.blockSignals(True)
    self.ui.horizontalSlider.setValue(msg["val"])
    self.ui.horizontalSlider.blockSignals(False)
three_pineapples
  • 11,579
  • 5
  • 38
  • 75
Achayan
  • 5,720
  • 2
  • 39
  • 61
  • Shouldn't `blockSignals()` be called on the UI object you are setting the value on (rather than just `self`)? – three_pineapples Jan 26 '16 at 03:05
  • aha sorry, I didn't noticed that – Achayan Jan 26 '16 at 03:10
  • I did try this [before](http://stackoverflow.com/questions/4146140/qslider-value-changed-signal#comment57709685_4146392). Result is almost as expected, except for this method also blocks the signals that are defined in Qt Designer which I don't want to block. Eg. If you connect a slider to a progress bar in Qt Designer and say "when slider's value changed, set progress bar's value" and then `slider.blockSignals` before updating `slider`'s value, then slider's value is updated but progress bar's is not. That's why, disconnecting and connecting the signals is even more appropriate in this case. – ceremcem Jan 26 '16 at 09:19