4

I’ve got a problem with QDoubleSpinBox. Editing behavior of “backspace” key somehow depends on the size of the suffix. If I set “m” as suffix, then set the cursor at the end of the spinbox and press “backspace”, the cursor jumps over the “m” suffix to the value which then can be edited with further “backspaces”. If I set the suffix to “mm” or any double-lettered word, the cursor remains at the end of the spinbox no matter how many “backspaces” I press.

I tried to debug what comes into “validate” method, and got a peculiar result: When the “backspace” is pressed while cursor is at the end of "0,00m", validate receives "0,00m". When the “backspace” is pressed while cursor is at the end of "0,00_m" validate receives "0,00__m" When the “backspace” is pressed while cursor is at the end of "0,00_mm" validate receives "0,00_m_mm"

What is the cause of such behavior and how can I overcome it?

# coding=utf-8
from PyQt5 import QtWidgets


class SpinBox(QtWidgets.QDoubleSpinBox):
    def __init__(self):
        super().__init__()

    def validate(self, text, index):
        res = super().validate(text, index)
        print(text, res, self.text())
        return res

if __name__ == "__main__":
    q_app = QtWidgets.QApplication([])
    sb = SpinBox()
    sb.setSuffix(" m")
    sb.show()
    q_app.exec_()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
den
  • 141
  • 1
  • 1
  • 6

1 Answers1

2

The source code for QDoubleSpinBox/QAbstractSpinBox is extremely convoluted when it comes to key-event handling - I couldn't work out what default behaviour is supposed to be, or even where it might be implemented. There might be a bug somewhere, but I wouldn't want to bet on it.

It looks like the only option is to reimplement keyPressEvent:

class SpinBox(QtWidgets.QDoubleSpinBox):
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Backspace:
            suffix = self.suffix()
            if suffix:
                edit = self.lineEdit()
                text = edit.text()
                if (text.endswith(suffix) and
                    text != self.specialValueText()):
                    pos = edit.cursorPosition()
                    end = len(text) - len(suffix)
                    if pos > end:
                        edit.setCursorPosition(end)
                        return
        super().keyPressEvent(event)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336