Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Overwriting QDoubleSpinBox's validate() does not prohibit input



  • I'm trying to expand a QDoubleSpinBox so that it accepts both comma and dot as decimal separator.
    Unfortunately, the validator always results in '0' (invalid) but still doesn't prohibit me from entering anything.

    Here's what I've done:

    #include <QDoubleSpinBox>
    
    class CuteDoubleSpinBox : public QDoubleSpinBox
    {
        Q_OBJECT
    
    public:
        explicit CuteDoubleSpinBox(QWidget* in_p_parent = Q_NULLPTR);
    
        virtual QValidator::State validate(QString& in_text, int& in_pos) const Q_DECL_OVERRIDE;
    
    private:
        QRegularExpressionValidator* m_p_validator;
    };
    
    CuteDoubleSpinBox::CuteDoubleSpinBox(QWidget* in_p_parent) : QDoubleSpinBox(in_p_parent),
        m_p_validator(new QRegularExpressionValidator(this))
    {
        m_p_validator->setRegularExpression(QRegularExpression("^-?[0-9]{0,64}([,.][0-9]{0,2})?$"));
    }
    
    QValidator::State CuteDoubleSpinBox::validate(QString& in_text, int& in_pos) const
    {
        QValidator::State state = m_p_validator->validate(in_text, in_pos);
    
        return state;
    }
    

    The RegEx permits both positive and negative numbers with a limitation to the number of digits on either side of the decimal separator, which can be a dot or comma.

    The RegEx is fine, I'm using it in other places already.
    I do not handle the validation any further where the SpinBox is being used.

    When I write the return value of the validate() to the log, the result is always '0', which means 'invalid', but I can still enter anything I want into the SpinBox. Both correct and incorrect inputs produce 0.



  • @qwasder85 said in Overwriting QDoubleSpinBox's validate() does not prohibit input:

    setRegularExpression

    First thought: in the examples e.g. https://doc.qt.io/qt-5/qregularexpressionvalidator.html#details you will see their reg exs are not anchored. Indeed it states:

    QRegularExpressionValidator automatically wraps the regular expression in the \\A and \\z anchors; in other words, it always attempts to do an exact match.

    Try removing your leading/trailing ^ & $, any better? Because if the Qt code really does what it states, it will be demanding you type in ^ & $ :)



  • @JonB Thank you. But no, unfortunately, makes no difference.



  • @qwasder85
    Hmm, I'm surprised that is not the issue?! I agree the reg ex looks reasonable when I scan it.

    • Put in qDebug() to show the text it is validating against.
    • Break it down. Start with, say, just . (dot) as the expression. How does that behave? Build from there. I have used validators and they worked as document for me; but these were on QLineEdits, not QSpinBoxes. The way Qt validators work is they should actually stop you typing unacceptable characters in, that does not seem to be happening to you?

    Maybe, being a spin box, it's not interested in your regular expression and just does it's own stuff. When you say "correct inputs produce 0", does that include a legitimate floating point number in your own locale? 1 would be a good example :)


  • Moderators

    @qwasder85 If I remember correctly, the validating is not done during input (for a QDoubleSpinBox) but on editingFinished(). So when you press enter or the spin box looses active focus.



  • @J-Hilk Hi, I figured that and tried a different approach. I have a custom QLineEdit control that CAN validate on input changed. If I use this control alone instead of the SpinBox, it works.
    If I now pass this control to the QSpinBox's setLineEdit()-function, it stops working again.
    There seems to be an additional abstraction layer between the SpinBox's input field and the QLineEdit behind it (maybe because the SpinBox can add pre/suffixes to the field?).


  • Moderators

    @qwasder85 maybe, I'm not overly familiar with the QCombobox source code 😕



  • @qwasder85 said in Overwriting QDoubleSpinBox's validate() does not prohibit input:

    The RegEx permits both positive and negative numbers with a limitation to the number of digits on either side of the decimal separator, which can be a dot or comma.

    You don't need a validator for this, you can just use QDoubleSpinBox::setRange to limit the upper/lower bounds, QDoubleSpinBox::setDecimals to set how many decimal places to accept finally QDoubleSpinBox::locale() takes care of chosing the appropriate decimal separator as suggeted by the system of the user

    P.S.
    A decimal numeber with 64 digits is HUGE and won't fit in any non-specially-devised storage type



  • @VRonin My spinbox needs to be able to handle commas AND dots as decimal separator. That's the crux. :D



  • Okay, seems that I've figured it out. Get this:

    When you set a suffix for the QSpinBox, the custom validation stops working. Because, apparently, the spinbox tries to validate the value WITH suffix (which is clearly wrong).
    If you check the cleanText()-function, it returns the value WITH suffix. Even though the documentation specifically states that the returned value excludes pre/suffix!

    Thanks Qt, very cool!


  • Moderators

    @qwasder85 time for a bug report :)


Log in to reply