0

I have a QLineEdit that accepts a string that will be evaluated at a javascript expression like "[0,3]" and connected to fire changes using editingFinished(). I added a validator so the user couldn't leave the input with a bad expression, but apparently I'm misunderstanding how the validator works, because if I return QValidator::Invalid, when the expression wouldn't be valid, user's can't type any mistakes (character won't disappear on backspace). For example, temporarily changing "[0,3]" to "[0,]" to fill in another number.

I've tried changing the validator to return to QValidator::Intermediate on bad expressions thinking that would be a happy medium letter users alter text, but setting bad text back to its previous value on unfocused or return, but that seems to let user's put in anything that want. For example, they can type in "[0," and click on something else and the input still has "[0," in it as opposed to jumping back to the way it was. Am I misunderstanding how the intermediate type works?

QValidator::Invalid         0   The string is clearly invalid.
QValidator::Intermediate    1   The string is a plausible intermediate value.
QValidator::Acceptable      2   The string is acceptable as a final result; 

i.e. it is valid.

Here is my current validator, which I just put on a QLineEdit:

class PointFValidator : public QValidator
{
    QValidator::State validate(QString &input, int &position) const;
    void fixup(QString &input) const;
};

QValidator::State PointFValidator::validate(QString &input, int &position) const
{
    try {
        evalPointF(input);
    } catch (std::exception &e) {
        return QValidator::Invalid;
    }

    return QValidator::Acceptable;
}

void PointFValidator::fixup(QString &input) const
{
}

And this is what actually tests the string to see if it's formatted correctly

QPointF evalPointF(QString s)
{
    //initGuile();

    QScriptEngine engine;
    QString program = "function frame() { return 9; }\n\n" + s;
    QScriptValue value = engine.evaluate(program);

    QStringList pair = value.toString().split(",");
    if (pair.length() < 2)
        throw std::runtime_error("invalid pointf string");

    return QPointF(pair[0].toFloat(), pair[1].toFloat());
}

Is the QValidator not what I need? Is it only for typing prevention? Do I need to listen to the change event, validate it myself, and set it back if it's not valid?

AAEM
  • 1,837
  • 2
  • 18
  • 26
voodoogiant
  • 2,118
  • 6
  • 29
  • 49

1 Answers1

-2

So trying to compile your code didn't work for me. The constness of the virtual functions in QValidator make it pretty much impossible to get your example code to compile.

So I would (like you mentioned at the end of your question) go and set up a signal to respond to the content changes of your QLineEdit, evaluate it, and then put the output somewhere helpful.

But based on the kinds of things you put in your evalPointF function, it looks like you are just writing an IDE for javascript.

Why not use the pattern that most IDE's already have of putting issues in another window, and using font's and formatting to modify the text, instead of actually changing the text?

Hope that helps.

AAEM
  • 1,837
  • 2
  • 18
  • 26
phyatt
  • 18,472
  • 5
  • 61
  • 80
  • 1
    I'm evaluating one JavaScript expression in a single-line text input and you assume I'm writing an IDE? As I said I have the input wired already, but want to validate the data beforehand using Qt's mechanisms. – voodoogiant Dec 22 '13 at 20:07