Search code examples
c++regexqtboost-spiritqregexp

Force QLineEdit to be a collection of double values


Consider this problem.

I have a QLineEdit in my tool and I should organize a support as follows. The text of LineEdit must contain only double values, separated my comas. F.e. 6.2 , 8, 9.0, 55 I also must validate, that user cannot input any other character but the numbers and comas. Also I should write a method which convert this text into vector. Initially I thought about QRegExp and boost::spirit. But it can be hard using these technique.

Any ideas?


Solution

  • Use next custom Validator.

    Header:

    #ifndef VALIDATOR_H
    #define VALIDATOR_H
    
    #include <QValidator>
    
    class Validator : public QValidator
    {
        Q_OBJECT
    public:
        explicit Validator(QObject *parent = 0);
    
    signals:
    
    public slots:
    public:
        QValidator::State validate(QString & input, int & pos) const;
    
    };
    
    #endif // VALIDATOR_H
    

    Cpp:

    #include "validator.h"
    #include <QDoubleValidator>
    #include <QDebug>
    Validator::Validator(QObject *parent) :
        QValidator(parent)
    {
    }
    
    QValidator::State Validator::validate(QString &input, int &pos) const
    {
        qDebug() << input<< pos;
        QDoubleValidator val;
        val.setLocale(QLocale(QLocale::German,QLocale::Germany));
        input.remove(" ");
        QStringList list = input.split(",");
        foreach ( QString var, list) {
            int i = 0;
            if(val.validate(var,i) == QValidator::Invalid)
                return QValidator::Invalid;
        }
        return QValidator::Acceptable;
    
    }
    

    Usage:

    ui->lineEdit->setValidator(new Validator);
    

    Explanation about: val.setLocale(QLocale(QLocale::German,QLocale::Germany));

    You said that you want use 6.2,... but . and , is different decimal point in different countries. So I wrote example accordingly to your question. German Locale always think that . is a correct point.

    But I recommend you to use locale-specific decimal point and use for this Purpose ; as separator instead of coma.

    There are mistakes, so try this. Edit(improved):

    QValidator::State Validator::validate(QString &input, int &pos) const
    {
        qDebug() << input<< pos;
        QRegExpValidator reg(QRegExp("[0-9]+(\\.[0-9]+)?$"));
        input.remove(" ");
        if(input.contains(",,") || input.startsWith(","))
            return QValidator::Invalid;
        QStringList list = input.split(",");
        qDebug()<< list;
        bool isOk = true;
        foreach ( QString var, list) {
            int i = 0;
            if(reg.validate(var,i) == QValidator::Invalid)
                return QValidator::Invalid;
            if(reg.validate(var,i) == QValidator::Intermediate)
                isOk = false;
        }
        if(isOk)
            return QValidator::Acceptable;
        else
            return QValidator::Intermediate;
    }