QLongLongValidator



  • Is there a version of the QIntValidator that supports 64 bit values? The documentation only mentions variants for int and double.
    If not, where do I get the source of the QIntValidator to customize it myself? I've searched the Qt folder on my computer but only found the corresponding header files.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    The implementation of these classes can be found in qvalidator.{h,cpp} in qtbase/src/gui/utils

    Your Qt folder will only contain the headers unless you installed the sources at the same time. You can grab them from the download section here or if you feel adventurous you can clone the git repository



  • Hi SGaist,

    thanks for the hint. I've downloaded the sources and adapted the datatypes to get validators for 32 and 64 bit ints and uints. For now I put them into my own small class and added that to my current project, but when trying to compile, I get a whole lot of "inconsistent dll linking" warnings and a few "unable to access private member" errors for example in line 31 of the source file. What have I done wrong?

    Here is the part of the header file for qint32, what I have omitted is just the same for uint32, int64 and uint64:

    @
    #ifndef MYQVALIDATOR_H
    #define MYQVALIDATOR_H

    #include <QValidator>

    QT_BEGIN_NAMESPACE

    class Q_GUI_EXPORT Qint32Validator : public QValidator
    {
    Q_OBJECT
    Q_PROPERTY(qint32 bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
    Q_PROPERTY(qint32 top READ top WRITE setTop NOTIFY topChanged)

    public:
    explicit Qint32Validator(QObject * parent = 0);

    Qint32Validator(qint32 bottom, qint32 top, QObject *parent = 0);
    ~Qint32Validator();
    
    QValidator::State validate(QString &, int &) const;
    void fixup(QString &input) const;
    
    void setBottom(qint32);
    void setTop(qint32);
    virtual void setRange(qint32 bottom, qint32 top);
    
    qint32 bottom() const { return b; }
    qint32 top() const { return t; }
    

    Q_SIGNALS:
    void bottomChanged(qint32 bottom);
    void topChanged(qint32 top);

    private:
    Q_DISABLE_COPY(Qint32Validator)

    qint32 b;
    qint32 t;
    

    };

    QT_END_NAMESPACE

    #endif // MYQVALIDATOR_H
    @

    And here are the parts of the source file relevant for qint32:

    @
    #include "myqvalidator.h"
    #include "C:/Qt/Sources/qtbase-opensource-src-5.2.1/src/corelib/kernel/qobject_p.h"
    #include "C:/Qt/Sources/qtbase-opensource-src-5.2.1/src/corelib/tools/qlocale_p.h"

    #include <limits.h>
    #include <math.h>

    QT_BEGIN_NAMESPACE

    Qint32Validator::Qint32Validator(QObject * parent)
    : QValidator(parent)
    {
    b = _I32_MIN;
    t = _I32_MAX;
    }

    Qint32Validator::Qint32Validator(qint32 minimum, qint32 maximum, QObject * parent)
    : QValidator(parent)
    {
    b = minimum;
    t = maximum;
    }

    Qint32Validator::~Qint32Validator()
    {
    }

    QValidator::State Qint32Validator::validate(QString & input, int&) const
    {
    QByteArray buff;
    if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
    return Invalid;
    }

    if (buff.isEmpty())
        return Intermediate;
    
    if (b >= 0 && buff.startsWith('-'))
        return Invalid;
    
    if (t < 0 && buff.startsWith('+'))
        return Invalid;
    
    if (buff.size() == 1 && (buff.at(0) == '+' || buff.at(0) == '-'))
        return Intermediate;
    
    bool ok, overflow;
    qint64 entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
    if (overflow || !ok)
        return Invalid;
    
    if (entered >= b && entered <= t) {
    

    /* locale().toInt(input, &ok); //this is useless, as it does nothing else but calling QLocalePrivate::bytearrayToLongLong again via a bunch of other function, which check for invalid chars (already done at the beginning of this function and the int limits (already done in this if statement)...
    */ return Acceptable;
    }

    if (entered >= 0) {
        // the -entered < b condition is necessary to allow people to type
        // the minus last (e.g. for right-to-left languages)
        return (entered > t && -entered < b) ? Invalid : Intermediate;
    } else {
        return (entered < b) ? Invalid : Intermediate;
    }
    

    }

    void Qint32Validator::fixup(QString &input) const
    {
    QByteArray buff;
    if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
    return;
    }
    bool ok, overflow;
    qint64 entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
    if (ok && !overflow)
    input = locale().toString(entered);
    }

    void Qint32Validator::setRange(qint32 bottom, qint32 top)
    {
    bool rangeChanged = false;
    if (b != bottom) {
    b = bottom;
    rangeChanged = true;
    emit bottomChanged(b);
    }

    if (t != top) {
        t = top;
        rangeChanged = true;
        emit topChanged(t);
    }
    
    if (rangeChanged)
        emit changed();
    

    }

    void Qint32Validator::setBottom(qint32 bottom)
    {
    setRange(bottom, top());
    }

    void Qint32Validator::setTop(qint32 top)
    {
    setRange(bottom(), top);
    }

    QT_END_NAMESPACE
    @


  • Lifetime Qt Champion

    It's because you are trying to access QLocale's d pointer which your class is not allowed to do



  • OK, I guessed that somehow from the error message. Let me precise my question: How do I get access to the validateChars function? The QIntValidator uses the same call and there it works obviously, although I haven't found something like "friend class QLocale".

    I've noticed that most of the "inconsistent dll linkage" warnings pops up in the moc_myqvalidator.cpp file instead of the original source file, so I guess I should learn a little bit about the Q_OBJECT macro in general. Do you have a good link about that at hand?


  • Lifetime Qt Champion

    You have the friendship relation upside down. QLocale says that QIntValidator is it's friend.



  • The "inconsistent dll linkage" was caused by the Q_GUI_EXPORT macro, so simply removing it fixed this sort of warnings.

    After reading through some articles, this "d" member is a popular method used together with a separate private class (which is the case here). Furthermore, it has been frequently mentioned that no one except the Qt developers should mess with this "d" member, so I guess the new validator variants would only be possible by hacking the Qt framework itself and recompiling everything. But not as a custom class like I imagined. :(


  • Lifetime Qt Champion

    The inconstancy probably comes from the fact that your a missing a define when build so you don't have the export effect expected from Q_GUI_EXPORT.

    You are correct, you would need to modify QLocale to make it accept your subclasses as friends


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.