Reputation: 1050
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.
Upvotes: 1
Views: 984
Reputation: 120608
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)
Upvotes: 1