Для решений у меня есть несколько подходов:
- Можно ограничить, чтобы первая цифра не была ".":
class DoubleValidator(QtGui.QDoubleValidator):
def validate(self, _input, pos):
res = super(DoubleValidator, self).validate(_input, pos)
if _input == "." and pos == 1:
res = (QtGui.QValidator.Invalid, _input, pos)
return res
# ...
validator_a = DoubleValidator(self, notation=QtGui.QDoubleValidator.StandardNotation)
self.le_a = QtWidgets.QLineEdit()
self.le_a.setValidator(validator_a)
# ...
Но то же самое должно быть сделано с«+» и «-», поскольку они порождают одну и ту же проблему, но не считаете ли вы ее неуместной?Например: как вы размещаете отрицательное значение?Вам нужно будет разместить хотя бы одну цифру, а затем переместить курсор в начало, чтобы разместить знак, что было бы слишком неудобно.Поэтому для меня это не разумное решение.
- Проверьте текст перед выполнением операции:
У пользователя не должно быть больше ограничений, чем необходимо, в этом случае я думаю, что это будетдостаточно, чтобы проверить случаи, когда даже число с плавающей точкой недопустимо, и установить в вычислении значение по умолчанию, например, «0»:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
validator_a = QtGui.QDoubleValidator(self, notation=QtGui.QDoubleValidator.StandardNotation)
self.le_a = QtWidgets.QLineEdit(textChanged=self.update_result)
self.le_a.setValidator(validator_a)
validator_b = QtGui.QDoubleValidator(self, notation=QtGui.QDoubleValidator.StandardNotation)
self.le_b = QtWidgets.QLineEdit(textChanged=self.update_result)
self.le_b.setValidator(validator_b)
self.result_label = QtWidgets.QLabel()
lay = QtWidgets.QHBoxLayout(self)
lay.addWidget(self.le_a)
lay.addWidget(QtWidgets.QLabel("+"))
lay.addWidget(self.le_b)
lay.addWidget(QtWidgets.QLabel("="))
lay.addWidget(self.result_label)
self.update_result()
@QtCore.pyqtSlot()
def update_result(self):
a = self.le_a.text()
b = self.le_b.text()
if a in ("", ".", "-", "+"):
a = 0
if b in ("", ".", "-", "+"):
b = 0
res = float(a) + float(b)
self.result_label.setNum(res)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
- не использовать QLineEdit, а QDoubleSpinBox:
Хотя QLineEdit позволяет ограничивать символы для проверки только чисел, лучше всего использовать QDoubleSpinBox, специализированный для получения числовых значений от пользователя:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.sp_a = QtWidgets.QDoubleSpinBox(valueChanged=self.update_result)
self.sp_b = QtWidgets.QDoubleSpinBox(valueChanged=self.update_result)
self.result_label = QtWidgets.QLabel()
lay = QtWidgets.QHBoxLayout(self)
lay.addWidget(self.sp_a)
lay.addWidget(QtWidgets.QLabel("+"))
lay.addWidget(self.sp_b)
lay.addWidget(QtWidgets.QLabel("="))
lay.addWidget(self.result_label)
self.update_result()
@QtCore.pyqtSlot()
def update_result(self):
a = self.sp_a.value()
b = self.sp_b.value()
res = a + b
self.result_label.setNum(res)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())