Как мне конвертировать.ввод в 0. в QLineEdit в PyQt5? - PullRequest
2 голосов
/ 18 июня 2019

Я пытаюсь создать оконную программу, в которой мне нужно вводить значения в несколько различных блоков QLineEdit, и при любом изменении текста будет запускаться функция вычисления (например, сумма различных блоков).

Мне уже удалось ограничить ввод числа с помощью QDoubleValidator, но я знаю, что если я введу что-либо кроме числа, программа завершится сбоем. Отсюда мой вопрос о разделителе десятичной точки, потому что я знаю, что будущие пользователи будут пытаться создать 0.* значения, используя только .*

В качестве примера я сделал следующее:

float_validator = QtGui.QDoubleValidator(self)
self.lineEdit_AC_CLmax.setValidator(float_validator)
CLmax  = float(self.lineEdit_AC_CLmax.text())

Я успешно проверил программу, используя числа, но всякий раз, когда я вводил ., программа зависала (очевидно, что заставить float('.') работать не получится).

Есть ли способ ограничить использование . сначала, разрешив его только после цифры # 1 в QLineEdit? В качестве альтернативы, есть ли способ преобразования . ввода в 0.?

1 Ответ

2 голосов
/ 18 июня 2019

Для решений у меня есть несколько подходов:

- Можно ограничить, чтобы первая цифра не была ".":

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_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...