Is it possible to set only 100 Percent value share limit to all QDoubleSpinBoxes?

I want to share 100 percent value limit to all QDoubleSpinBoxes. If it is possible how to do?

    self.SpinBox_one = QtWidgets.QDoubleSpinBox()
    self.SpinBox_two = QtWidgets.QDoubleSpinBox()
    self.SpinBox_three = QtWidgets.QDoubleSpinBox()
    self.SpinBox_four = QtWidgets.QDoubleSpinBox()
    self.SpinBox_five = QtWidgets.QDoubleSpinBox()

for example i have 5 QDoubleSpinBoxes as above. If i insert 30 in self.SpinBox_one, Remaining is 70, then 70 only should be useful for remaining 4 QDoubleSpinBoxes. And again if i insert 50 in self.SpinBox_two, Remaining should be 20, and it should be useful to remaining QDoubleSpinBoxes. and again if i insert 20 in self.SpinBox_three, remaining is 0. And now remaining QDoubleSpinBoxes are should be 0. Below is my example code:

from PyQt5 import QtWidgets
from PyQt5 import QtCore

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.SpinBox_one = QtWidgets.QDoubleSpinBox()
        self.SpinBox_two = QtWidgets.QDoubleSpinBox()
        self.SpinBox_three = QtWidgets.QDoubleSpinBox()
        self.SpinBox_four = QtWidgets.QDoubleSpinBox()
        self.SpinBox_five = QtWidgets.QDoubleSpinBox()

        form_widget = QtWidgets.QWidget()
        form_layout = QtWidgets.QFormLayout(form_widget)
        form_layout.addRow("1", self.SpinBox_one)
        form_layout.addRow("2", self.SpinBox_two)
        form_layout.addRow("3", self.SpinBox_three)
        form_layout.addRow("4", self.SpinBox_four)
        form_layout.addRow("5", self.SpinBox_five)

        form_widget.setFixedSize(form_widget.sizeHint())
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        hlay1 = QtWidgets.QHBoxLayout()
        hlay1.addWidget(form_widget)
        hlay1.addStretch()

        vboxlayout = QtWidgets.QVBoxLayout(central_widget)
        vboxlayout.addLayout(hlay1)
        self.resize(50, 50)

        ##
        self.SpinBox_one.setMaximum(100.00)
        #self.SpinBox_two.setMaximum(100.00)
        #self.SpinBox_three.setMaximum(100.00)
        #self.SpinBox_four.setMaximum(100.00)
        #self.SpinBox_five.setMaximum(100.00)

        self.SpinBox_one.valueChanged.connect(self.SpinBox_one_changed)
        self.SpinBox_two.valueChanged.connect(self.SpinBox_two_changed)
        self.SpinBox_three.valueChanged.connect(self.SpinBox_three_changed)
        self.SpinBox_four.valueChanged.connect(self.SpinBox_four_changed)
    def SpinBox_one_changed(self):
         self.SpinBox_two.setMaximum(100 - self.SpinBox_one.value())

    def SpinBox_two_changed(self):
         self.SpinBox_three.setMaximum(100-self.SpinBox_one.value() - self.SpinBox_two.value())
         
    def SpinBox_three_changed(self):
         self.SpinBox_four.setMaximum(100-self.SpinBox_one.value() - self.SpinBox_two.value() - self.SpinBox_three.value())

    def SpinBox_four_changed(self):
         self.SpinBox_five.setMaximum(100-self.SpinBox_one.value() - self.SpinBox_two.value() - self.SpinBox_three.value() - self.SpinBox_four.value())

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

It is working up to fourth but fifth is not working as expect.

Answer

It is simpler to operate on a list of spin boxes rather than keep a separate name for each one. Each QDoubleSpinBox’s valueChanged signal is connected to the function limit() that limits the maximum values of the remaining boxes. First count the total value up to the spin box that was just changed. Then for the spin boxes after it, set their maximum value to the remaining amount out of 100 and increment the running total.

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        form_widget = QtWidgets.QWidget()
        form_layout = QtWidgets.QFormLayout(form_widget)

        self.boxes = []
        for i in range(5):
            box = QtWidgets.QDoubleSpinBox(maximum=100, valueChanged=self.limit)
            form_layout.addRow(str(i + 1), box)
            self.boxes.append(box)

        form_widget.setFixedSize(form_widget.sizeHint())
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        hlay1 = QtWidgets.QHBoxLayout()
        hlay1.addWidget(form_widget)
        hlay1.addStretch()

        vboxlayout = QtWidgets.QVBoxLayout(central_widget)
        vboxlayout.addLayout(hlay1)
        self.resize(50, 50)

    def limit(self, value):
        i = self.boxes.index(self.sender())
        total = value + sum(box.value() for box in self.boxes[:i])
        for box in self.boxes[i + 1:]:
            box.blockSignals(True) # Avoid extra calls to limit()
            box.setMaximum(100 - total)
            box.blockSignals(False)
            total += box.value()

Edit, keeping the original __init__ code:

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.SpinBox_one = QtWidgets.QDoubleSpinBox()
        self.SpinBox_two = QtWidgets.QDoubleSpinBox()
        self.SpinBox_three = QtWidgets.QDoubleSpinBox()
        self.SpinBox_four = QtWidgets.QDoubleSpinBox()
        self.SpinBox_five = QtWidgets.QDoubleSpinBox()

        form_widget = QtWidgets.QWidget()
        form_layout = QtWidgets.QFormLayout(form_widget)
        form_layout.addRow("1", self.SpinBox_one)
        form_layout.addRow("2", self.SpinBox_two)
        form_layout.addRow("3", self.SpinBox_three)
        form_layout.addRow("4", self.SpinBox_four)
        form_layout.addRow("5", self.SpinBox_five)
        
        form_widget.setFixedSize(form_widget.sizeHint())
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        hlay1 = QtWidgets.QHBoxLayout()
        hlay1.addWidget(form_widget)
        hlay1.addStretch()

        vboxlayout = QtWidgets.QVBoxLayout(central_widget)
        vboxlayout.addLayout(hlay1)
        self.resize(50, 50)

        ##
        self.SpinBox_one.setMaximum(100.00)
        #self.SpinBox_two.setMaximum(100.00)
        #self.SpinBox_three.setMaximum(100.00)
        #self.SpinBox_four.setMaximum(100.00)
        #self.SpinBox_five.setMaximum(100.00)

        self.SpinBox_one.valueChanged.connect(self.limit)
        self.SpinBox_two.valueChanged.connect(self.limit)
        self.SpinBox_three.valueChanged.connect(self.limit)
        self.SpinBox_four.valueChanged.connect(self.limit)
        
        self.boxes = [self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five]