How to get out of a loop of inter-updating widgets?

后端 未结 1 637
暗喜
暗喜 2021-01-21 19:25

I am writing a small GUI with PyQt5 that links two series of values (let\'s call them a, b, c and alpha, beta respectively). All numbers are input via QDoubleSpinBox widgets.

1条回答
  •  天涯浪人
    2021-01-21 19:59

    From what I understand you want that if "a", "b" or "c" is modified by the user you should only modify "alpha" and "beta" using f1, and change "alpha" and "beta" it does not change "a", "b" and "c". The same for the case of "alpha" and "beta" with f2. If so, then the solution is to block the emission of signals from the elements that are changed programmatically since this is the reason for the infinite recursion using blockSignals().

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    def f1(a, b, c):
        return 1 / (1 + a ** 2 + b ** 2 + c ** 2) ** 0.5, a + b + c
    
    
    def f2(alpha, beta):
        return (
            alpha + beta,
            1 / (alpha ** 2 + beta ** 2 + 1),
            (alpha ** 2 + beta ** 2) ** 0.5,
        )
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            max_f = 1.7976931348623157e308
            min_f = -max_f
            self.m_a_dsp = QtWidgets.QDoubleSpinBox(
                value=0,
                valueChanged=self.update_alpha_beta,
                minimum=min_f,
                maximum=max_f,
            )
            self.m_b_dsp = QtWidgets.QDoubleSpinBox(
                value=0,
                valueChanged=self.update_alpha_beta,
                minimum=min_f,
                maximum=max_f,
            )
            self.m_c_dsp = QtWidgets.QDoubleSpinBox(
                value=0,
                valueChanged=self.update_alpha_beta,
                minimum=min_f,
                maximum=max_f,
            )
            self.m_alpha_dsp = QtWidgets.QDoubleSpinBox(
                value=0,
                valueChanged=self.update_a_b_c,
                minimum=min_f,
                maximum=max_f,
            )
            self.m_beta_dsp = QtWidgets.QDoubleSpinBox(
                value=0,
                valueChanged=self.update_a_b_c,
                minimum=min_f,
                maximum=max_f,
            )
    
            lay = QtWidgets.QGridLayout(self)
            lay.addWidget(self.m_a_dsp, 0, 0, 1, 2)
            lay.addWidget(self.m_b_dsp, 0, 2, 1, 2)
            lay.addWidget(self.m_c_dsp, 0, 4, 1, 2)
            lay.addWidget(self.m_alpha_dsp, 1, 0, 1, 3)
            lay.addWidget(self.m_beta_dsp, 1, 3, 1, 3)
    
        @QtCore.pyqtSlot()
        def update_alpha_beta(self):
            alpha, beta = f1(
                self.m_a_dsp.value(), self.m_b_dsp.value(), self.m_c_dsp.value()
            )
            for spinbox, value in zip(
                (self.m_alpha_dsp, self.m_beta_dsp), (alpha, beta)
            ):
                spinbox.blockSignals(True)
                spinbox.setValue(value)
                spinbox.blockSignals(False)
    
        @QtCore.pyqtSlot()
        def update_a_b_c(self):
            a, b, c = f2(self.m_alpha_dsp.value(), self.m_beta_dsp.value())
    
            for spinbox, value in zip(
                (self.m_a_dsp, self.m_b_dsp, self.m_c_dsp), (a, b, c)
            ):
                spinbox.blockSignals(True)
                spinbox.setValue(value)
                spinbox.blockSignals(False)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    0 讨论(0)
提交回复
热议问题