How to prevent a QDoubleSpinBox from changing values
Question: I've written a GUI for a script that does some geometrical calculations.
Certain ranges of values break the computation (e.g. find the intersection of
two shapes that don't intersect.) I raise exceptions in those cases. I'd like
to prevent the user from adjusting the spinbox value beyond the point where
exceptions are raised.

I've tried overwriting the validator method for the QDoubleSpinBox. This works
great when I manually enter values with the keyboard. But, it doesn't prevent
me from clicking the up and down arrows.

How I can limit the ability of the user to run-up the values outside of the
acceptable range?

Note: The actual `some_complicated_function` involves the values from 5
different spinboxes.

    
    
    from PyQt4 import QtCore, QtGui
    import sys
    
    def some_complicated_function(val_a):
        if val_a + 3 < 10:
            return True
        else:
            raise Exception("Giant number!")
    
    class SpinBoxSpecial(QtGui.QDoubleSpinBox):
        def validate(self, value, pos):
    #         print float(value)
            try:
                some_complicated_function(float(value))
                print "yup"
                return QtGui.QValidator.Acceptable, QtGui.QValidator.Acceptable
            except:
                print "nope"
                return QtGui.QValidator.Invalid, QtGui.QValidator.Invalid
    
    a = QtGui.QApplication(sys.argv)       
    w = QtGui.QMainWindow()
    w.resize(320, 100)
    w.setWindowTitle("PyQT Python Widget!") 
    
    spinbox = SpinBoxSpecial(w)
    spinbox.move(20, 20)
    spinbox.CorrectionMode = QtGui.QAbstractSpinBox.CorrectToPreviousValue
    
    w.show() 
    
    sys.exit(a.exec_())
    

**Edit:** The basic ask is: I want to call a function when the value of a
spinbox changes (via mouse or keyboard). If that function throws an exception,
I want the value of the spinbox to revert to what it was.


Answer: Here is a simple way to dynamically set the range on a spinbox:

    
    
    class SpinBoxSpecial(QtGui.QDoubleSpinBox):
        def __init__(self, parent=None):
            super(SpinBoxSpecial, self).__init__(parent)
            self._last = self.value()
            self.valueChanged.connect(self.handleValueChanged)
    
        def handleValueChanged(self, value):
            try:
                some_complicated_function(float(value))
                print "yup", value
                self._last = value
            except:
                print "nope", value
                if value > self._last:
                    self.setMaximum(self._last)
                else:
                    self.setMinimum(self._last)
    

**EDIT** :

Just realized the above won't work correctly if a value is typed in directly,
because it could fix the min/max too early. So maybe this would be better:

    
    
        def handleValueChanged(self, value):
            try:
                some_complicated_function(float(value))
                print "yup", value
                self._last = value
            except:
                print "nope", value
                self.setValue(self._last)
    

