Search code examples
regexqtqmldecimallocale

Specify decimal symbol in QML application


Specify decimal symbol in QML

I want to have the user only use the dot for decimal symbol, regardless on which locale his machine is. For example we support en_US and nl_NL, but in both language settings we want to limit the user to only use the dot as decimal symbol. (Due legacy system it communicates with)

I tried different ways:

QLocale newLanguageLocale = QLocale(QLocale::Dutch, QLocale::Netherlands);
newLanguageLocale.setNumberOptions(QLocale::c().numberOptions());
QLocale::setDefault(newLanguageLocale);

And in QML:

Item 
{
    property int numberOfDecimals: 3

    TextInput
    {
        validator: doubleChecker
    }

    DoubleValidator
    {
        id: doubleChecker
        decimals: numberOfDecimals
        notation: DoubleValidator.StandardNotation
    }
}
  • locale en_US: Can enter dot, everything works as expected
  • locale nl_NL: Can enter dot but that is used as thousand seperator. Comma can still be used. (Not wanted)

So I tried to solve it in the TextInput by using a RegExpValidator, but that doesn't allow me to create a regular expression of the fly. Which I need because the numberOfDecimals can be changed.

RegExpValidator
{
    id: doubleChecker
    //regExp: /^-?[0-9]+(\.[0-9]{1,3})?$/   // This works (3 decimals), but I want to be able have a specified numberOfDecimals (some fields have different settings)
    regExp: new RegExp('/^-?[0-9]+(\.[0-9]{1,' + numberOfDecimals + '})?$/') // doesn't work, can enter unlimited amount of decimals. Also when field is empty, I cannot type
}

Any idea how to proceed? Did I make a syntax error in the RegExpValidator


Solution

  • You need to use a constructor notation properly. That means:

    • You need to use double escapes to define a regex escape (that is, "\\." to match a literal dot, or it will match any character but a line break char), or enclose it with [...], a character class
    • You need no leading/trailing /, known as regex delimiters, as these are used in a regex literal notation.

    So, you need

    new RegExp("^-?[0-9]+([.][0-9]{1," + numberOfDecimals + "})?$")
    

    or

    new RegExp("^-?[0-9]+(\\.[0-9]{1," + numberOfDecimals + "})?$")
    

    It is correct to use the constructor notation here as only this notation allows passing a variable to the regex pattern.

    See more about how to use RegExp at MDN.