QSpinBox (QAbstractSpinBox) allows custom validation by re-implementing validate and fixup.
fixup signature is void fixup(QString &) and is supposed to alter the input passed by reference. In PySide, the signature is adjusted so that the function returns a string. However, this does not seem to work. The returned value is ignored.
See the example below. It shows a QSpinBox that would allow only multiples of 5. Type a number that is not a multiple of five, and unfocus the window.
Expected behavior: the value is rounded to the next 5, e.g. typing in 6 should change the text to 10.
Observed behavior: the previous value in the spinbox (for example 0) is restored no matter what the input was.
from PySide6.QtGui import QValidator
from PySide6.QtWidgets import QApplication, QSpinBox
class MySpinBox(QSpinBox):
    def __init__(self, parent=None):
        super().__init__(parent)
    def stepBy(self, steps):
        self.setValue(self.value() + 5 * steps)
    def validate(self, input, pos):
        if not input:
            return QValidator.State.Intermediate
        try:
            number = int(input)
        except ValueError:
            return QValidator.State.Invalid
        if number % 5 == 0:
            return QValidator.State.Acceptable
        else:
            return QValidator.State.Intermediate
    def fixup(self, input):
        number = int(input)
        # Round up to next multiple of 5.
        number += 5 - number % 5
        return str(number)
if __name__ == "__main__":
    app = QApplication()
    spinbox = MySpinBox()
    spinbox.show()
    app.exec()
See also a similar previous issue affecting QValidator https://bugreports.qt.io/browse/PYSIDE-106