Исправьте значения, которые вводятся в двойной спин-ящик в PyQt - PullRequest
2 голосов
/ 11 марта 2012

Я хочу создать поле двойного вращения, которое изменяет значения с шагом 0,2.Но когда пользователь вводит неверное значение в соответствии с шагами.Я нормализую это до ближайшего правильного значения.Я пробовал что-то вроде кода, показанного ниже, но я не знаю, как остановить ввод значений, таких как 0,5Пожалуйста, помогите мне в этом.


    from PyQt4.QtCore import *
    from PyQt4.QtGui import *

    class SigSlot(QWidget):
        def __init__(self, parent=None):
            QWidget.__init__(self, parent)
            self.setWindowTitle('spinbox value')
            self.resize(250,150)
            self.lcd1 = QLCDNumber(self)
            self.spinbox1 = QDoubleSpinBox(self)
            self.spinbox1.setSingleStep(0.2)
            self.spinbox1.setCorrectionMode(1)
             # create a Grid Layout
            grid = QGridLayout()
            grid.addWidget(self.lcd1, 0, 0)
            grid.addWidget(self.spinbox1, 1, 0)
            self.setLayout(grid)
             # allows access to the spinbox value as it changes
            self.connect(self.spinbox1, SIGNAL('valueChanged(double)'), self.change_value1)

        def change_value1(self, event):
            val = self.spinbox1.value()
            self.lcd1.display(val)

    app = QApplication([])
    qb = SigSlot()
    qb.show()
    app.exec_()

Ответы [ 2 ]

5 голосов
/ 11 марта 2012

У вас есть два варианта:

  • Вы можете создать подкласс QSpinBox, переопределить validate метод и использовать соответствующий Q*Validator (например, QRegExpValidator) внутри.
  • Вы можете проверить значение в слоте, подключенном к valueChanged перед использованием, и при необходимости исправить его.

Поскольку вы уже используете сигнал valueChanged, второй вариант должен быть достаточно простым для реализации. Просто измените свой change_value метод следующим образом:

def change_value1(self, val): # new value is passed as an argument
    # so no need for this
    # val = self.spinbox1.value()

    new_val = round(val*5)/5 # one way to fix
    if val != new_val:       # if value is changed, put it in the spinbox
        self.spinbox1.setValue(new_val)

    self.lcd1.display(new_val)

Кстати, поскольку вы используете только одну десятичную точность, было бы логично также использовать:

self.spinbox1.setDecimals(1)

в вашем __init__. И попробуйте использовать новый стиль сигналов и слотов . i.e.:

self.connect(self.spinbox1, SIGNAL('valueChanged(double)'), self.change_value1)

можно записать как:

self.spinbox1.valueChanged[float].connect(self.change_value1)

Редактировать

подклассы:

class MySpinBox(QDoubleSpinBox):
    def __init__(self, parent=None):
        super(MySpinBox, self).__init__(parent)
        # any RegExp that matches the allowed input
        self.validator = QRegExpValidator(QRegExp("\\d+[\\.]{0,1}[02468]{0,1}"), self)

    def validate(self, text, pos):
        # this decides if the entered value should be accepted
        return self.validator.validate(text, pos)

тогда вместо QDoubleSpinBox вы бы использовали MySpinBox и оставили бы проверку ввода этому классу.

0 голосов
/ 11 марта 2012

В вашем методе изменения значения вы можете сделать что-то вроде этого

val = round(self.spinbox1.value(), 1)
if val/2*10 - int(val/2*10):
    val = round(val, 1) + .1

Возможно, это не лучший способ, но он работает.

...