HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

PyQt5 validator for decimal numbers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
validatordecimalnumberspyqt5for

Problem

This class is similar to QDoubleValidator, but it improves slightly on the editing comfort. The comments mention "comma" but it's actually the decimal point of your locale (comma for me).

class DecimalValidator(QDoubleValidator):
    def __init__(self, *args):
        QDoubleValidator.__init__(self, *args)
        self.setNotation(QDoubleValidator.StandardNotation)
    def validate(self, input, pos):
        sep = self.locale().decimalPoint()
        if pos and (input[pos-1]==sep) and (sep in input[pos:]):
            # When we're left of the comma, and comma is pressed,
            # remove the inserted comma and move right of the old comma.
            input = input[:pos-1] + input[pos:]
            pos = input.find(sep)+1
        elif sep in input[:pos] and (len(input.split(sep)[1]) > self.decimals()):
            # When we're right of the comma, and all decimal places are used already,
            # go into overwrite mode (by removing the old digit)
            input = input[:pos] + input[pos+1:]
        return QDoubleValidator.validate(self, input, pos)

Solution

I noticed your commenting style and decided it's worthy of it's own answer.

You admit the comma is not always a comma. So don't call it a comma. I went for separator, which is as neutral as it gets. If you think of something better, go for it.

Also, I think your comments would fit better as a docstring than as comments.

class DecimalValidator(QDoubleValidator):
    def __init__(self, *args):
        QDoubleValidator.__init__(self, *args)
        self.setNotation(QDoubleValidator.StandardNotation)
    def validate(self, input, pos):
        '''
        When we're left of the separator, and separator is pressed,
        remove the inserted separator and move right of the old separator.
        When we're right of the separator, and all decimal places are used already,
        go into overwrite mode (by removing the old digit)
        '''
        sep = self.locale().decimalPoint()
        if pos and (input[pos-1]==sep) and (sep in input[pos:]):
            input = input[:pos-1] + input[pos:]
            pos = input.find(sep)+1
        elif sep in input[:pos] and (len(input.split(sep)[1]) > self.decimals()):
            input = input[:pos] + input[pos+1:]
        return QDoubleValidator.validate(self, input, pos)

Code Snippets

class DecimalValidator(QDoubleValidator):
    def __init__(self, *args):
        QDoubleValidator.__init__(self, *args)
        self.setNotation(QDoubleValidator.StandardNotation)
    def validate(self, input, pos):
        '''
        When we're left of the separator, and separator is pressed,
        remove the inserted separator and move right of the old separator.
        When we're right of the separator, and all decimal places are used already,
        go into overwrite mode (by removing the old digit)
        '''
        sep = self.locale().decimalPoint()
        if pos and (input[pos-1]==sep) and (sep in input[pos:]):
            input = input[:pos-1] + input[pos:]
            pos = input.find(sep)+1
        elif sep in input[:pos] and (len(input.split(sep)[1]) > self.decimals()):
            input = input[:pos] + input[pos+1:]
        return QDoubleValidator.validate(self, input, pos)

Context

StackExchange Code Review Q#110298, answer score: 3

Revisions (0)

No revisions yet.