[Background]
The default print() function of QScriptEngine prints the result to the terminal of Qt Creator IDE for debugging purpose. As a result, the output must be redirected to our texteditor if we are going to make a ECMA script interpreter ourselves.
This part of the document "Making Applications Scriptable" remains untouched since Qt 4.3.
Section "Redefining print()":
Qt Script provides a built-in print() function that can be useful for simple debugging purposes. The built-in print() function writes to standard output. You can redefine the print() function (or add your own function, e.g. debug() or log()) that redirects the text to somewhere else. The following code shows a custom print() that adds text to a QPlainTextEdit.
So here is the suggested re-definition of print():
QScriptValue QtPrintFunction(QScriptContext *context, QScriptEngine *engine)
{
QString result;
for (int i = 0; i < context->argumentCount(); ++i) {
if (i > 0)
result.append(" ");
result.append(context->argument(i).toString());
}
QScriptValue calleeData = context->callee().data();
QPlainTextEdit *edit = qobject_cast<QPlainTextEdit*>(calleeData.toQObject());
edit->appendPlainText(result);
return engine->undefinedValue();
}
Then, expose it to the script engine:
QScriptEngin engine;
QScriptValue fun = engine.newFunction(QtPrintFunction);
fun.setData(eng.newQObject(&edit));
engine.globalObject().setProperty("print", fun);
[Question]
Here is what I've done to change the function
QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
{
QString result;
for (int i = 0; i < context->argumentCount(); ++i) {
if (i > 0)
result.append(" ");
result.append(context->argument(i).toString());
}
/*
QScriptValue calleeData = context->callee().data();
QPlainTextEdit *edit = qobject_cast<QPlainTextEdit*>(calleeData.toQObject());
edit->appendPlainText(result);
return engine->undefinedValue();
*/
return engine->toScriptValue(result); // ---> return the result directly
}
// ...
QScriptEngin engine;
QScriptValue fun = engine.newFunction(myPrintFunction);
fun.setData(eng.newQObject(&edit));
engine.globalObject().setProperty("print", fun);
which I think is more reasonable to me: returning an evaluated QScriptValue from script engine, and the value can later be translated to QString for output. This bypass the need of dynamic type cast, which could become messy especially for customized QObjects.
Besides, the original QtPrintFunction() carrying the pointer of GUI class for output all the time (QPlainTextEdit in the example), which seems to mess with the concept of separating GUI and the function code. Hence, I am suspecting Qt might do it just for returning an "undefined value" because she rather directly print the result in the function than return it.
But I am not sure, since my own myPrintFunction() works just fine. Any ideas?
[Example]
Input:
print(123);
Output (Qt Document QtPrintFunction()):
123
undefined
Directly print 123 to the output widget, and return an "undefined value" as QScriptValue.
Output (My version myPrintFunction()):
123
Returning 123 instead of undefined as QScriptValue, which can be translated by QScripValue::toString later to the output widget.
[Edit]:
I've found myPrintFunction didn't work well in loop, but I don't know how to explain it.
Here are different outputs with two types of print function but using the same script:
Input:
for (i = 0; i < 3; i++)
print(i);
Output (Qt Document QtPrintFunction() ):
0
1
2
undefined
Output (myPrintFunction()):
2
In fact, my myPrintFunction() only allows me to print once per script, and only the last print function will do his job. The script
print("Stack");
print("Overflow");
result will be
Overflow
for myPrintFunction(), which is not what I want.
It seems the returning of an "Undefined Value" is NECESSARY for print function. But why???
Aucun commentaire:
Enregistrer un commentaire