Javascript 什么';返回一个“s”是什么意思;“未定义值”;当重新定义“时”;打印();QScript引擎的函数? [背景]
的默认Javascript 什么';返回一个“s”是什么意思;“未定义值”;当重新定义“时”;打印();QScript引擎的函数? [背景],javascript,c++,qt,interpreter,read-eval-print-loop,Javascript,C++,Qt,Interpreter,Read Eval Print Loop,的默认print()函数将结果打印到Qt Creator IDE的终端以进行调试。因此,如果我们要自己制作ECMA脚本解释器,输出必须重定向到我们的texteditor 自Qt4.3以来,文档的这一部分未被触及 第节: Qt脚本提供了一个内置的print()函数,可用于 简单的调试目的。内置的print()函数写入 标准输出。您可以重新定义print()函数(或添加 自己的函数,例如debug()或log()),将文本重定向到 在别的地方。下面的代码显示了添加 将文本添加到QPlainTextE
print()
函数将结果打印到Qt Creator IDE的终端以进行调试。因此,如果我们要自己制作ECMA脚本解释器,输出必须重定向到我们的texteditor
自Qt4.3以来,文档的这一部分未被触及
第节:
Qt脚本提供了一个内置的print()函数,可用于
简单的调试目的。内置的print()函数写入
标准输出。您可以重新定义print()函数(或添加
自己的函数,例如debug()或log()),将文本重定向到
在别的地方。下面的代码显示了添加
将文本添加到QPlainTextEdit
下面是建议重新定义print()
:
我认为这对我来说更合理:从脚本引擎返回一个经过计算的QScriptValue
,然后可以将该值转换为QString
进行输出。这绕过了动态类型转换的需要,动态类型转换可能会变得混乱,特别是对于定制的QObject
对于这两种打印功能,下面是对脚本引擎的说明:
QScriptEngine *engine = new QScriptEngine(this);
QTextEdit *input = new QTextEdit(this);
QTextEdit *output = new QTextEdit(this);
// Use documented print function :
QScriptValue fun = engine->newFunction(QtPrintFunction);
// Use my revised print function :
// QScriptValue fun = engine->newFunction(myPrintFunction);
fun.setData(engine->newQObject(output));
engine->globalObject().setProperty("print", fun);
评价和产出:
QString command = input->toPlainText();
QScriptValue result = engine->evaluate(command);
output->append(result.toString());
[可编译代码] (需要Qt版本>4) test.pro
QT+=核心gui小部件脚本
目标=测试
模板=应用程序
SOURCES+=main.cpp\
console.cpp
HEADERS+=console.h
快速回答:不需要返回未定义的值。你可以退回你想要的任何东西。然而,engine->evaluate()
只能返回一个值,我认为这是造成混淆的原因
查看评估代码:
QString command = input->toPlainText();
QScriptValue result = engine->evaluate(command);
output->append(result.toString());
这将获取脚本字符串并对其求值,将结果值分配到result
,然后将其附加到QTextEdit
控件中。evaluate()
的返回值将是脚本的最后一个值。例如:
QString command = "var a=1, b=2; a; b;";
QScriptValue result = engine->evaluate(command);
output->append(result.toString());
print("Stack");
print("Overflow");
result
将包含2个,然后将其记录到QTextEdit
控件中
那么,发生了什么事?以该输入为例:
QString command = "var a=1, b=2; a; b;";
QScriptValue result = engine->evaluate(command);
output->append(result.toString());
print("Stack");
print("Overflow");
使用QtPrintFunction
时,作为QtPrintFunction
实现的一部分,“Stack”和“Overflow”被添加到输出
控件中。当evaluate()
完成时,最后一条语句是print(“Overflow”)
,它返回undefined。然后,求值代码获取该返回值并将其添加到输出
,结果是:
Stack
Overflow
undefined
使用myPrintFunction
时,该实现不会将任何内容记录到输出中,而是返回值。结果是evaluate()
函数只返回最后一个值(“溢出”),从而产生以下输出:
Overflow
这就是你所看到的
由于要将输出重定向到自己的自定义文本编辑器,因此需要更改此代码块:
QScriptEngine *engine = new QScriptEngine(this);
QTextEdit *input = new QTextEdit(this);
//QTextEdit *output = new QTextEdit(this);
YourCustomEditor *output = getYourCustomEditor();
// Use my revised print function :
QScriptValue fun = engine->newFunction(myPrintFunction);
fun.setData(engine->newQObject(output)); // pass your editor in
engine->globalObject().setProperty("print", fun);
然后在myPrintFunction
中,您需要以类似于QtPrintFunction
的方式将输出发送到YourCustomEditor
。然后,您不再需要从evaluate()
输出结果:
QString命令=input->toPlainText();
QScript值结果=引擎->评估(命令);
//输出->附加(result.toString()) 并不是说必须返回undefinedValue()
,而是当您这样做时,它与不返回任何内容是一样的。或者本质上,就像您将函数声明为void print(…)
,可以这么说
这就是QtPrintFunction
的作用——它返回“nothing”。但它确实有一个副作用,即在调用内部数据对象时将其参数附加到该对象。这就是为什么要在output
对象中获得传递给print
的所有值
现在,当您调用engine->evaluate()
时,它将返回上一次计算的表达式的值。因此,使用myPrintFunction
只能获得last值
因此,如果您要输入以下内容:
print("Stack");
print("Overflow");
"garbage";
您将只返回垃圾
(双关语),因为这是最后一个计算表达式
但是,如果您要输入以下内容:
print("Stack") + '\n' +
print("Overflow");
正如您所期望的,您将获得这两个值
此外,如果您输入:
result = "";
for (i = 0; i < 3; i++)
result += print(i) + '\n';
这将按照您期望的方式“工作”。唯一的问题是无法清除result
的值。如果这对你有用的话,那就这样吧
有一种更好的方法可以做到这一点,可能是定义一个类,例如:
class QTrace: public QObject
{
...
void clear();
void append(const QString& value);
const QString& get();
}
并将该类的对象传递给fun.setData(引擎->新对象(跟踪))
并将函数定义为:
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());
}
result.append('\n');
QScriptValue calleeData = context->callee().data();
QTrace *trace = qobject_cast<QTrace*>(calleeData.toQObject());
trace->append(result);
return engine->undefinedValue();
}
或者可能还有其他方法,但希望能帮助您朝着正确的方向前进。括号中的旁注是,QtScripts已经“完成”(甚至可能已经过时了?)有一段时间。这是在2013年毕尔巴鄂QtCS之后的想法,当时我在那里。但不是Javascript。我认为QScriptEngine
可以同时读取它们,所以基本上我的目标是专注于Javascirpt。或者你建议我删除qtscript
标记?我只是想写一篇文章,你可能想放弃使用QtScript
(顺便说一下,这是语法错误:qscriptengine;
)它是在当时创建的,因为允许简单的脚本选项很有趣,例如我们在游戏开发者的游戏创建者IDE中使用了它,但后来Qt项目认为新的v4引擎是未来的发展方向。您如何“输出”使用myPrintFunction
打印的内容?输出显示在哪里?请在您的问题中指定这一点爱丽:谢谢!这很清楚,答案是…比我想象的要简单得多。哈哈,事情真的会变得很混乱
class QTrace: public QObject
{
...
void clear();
void append(const QString& value);
const QString& get();
}
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());
}
result.append('\n');
QScriptValue calleeData = context->callee().data();
QTrace *trace = qobject_cast<QTrace*>(calleeData.toQObject());
trace->append(result);
return engine->undefinedValue();
}
trace->clear();
QScriptValue result = engine->evaluate(command);
if(result.isError())
output->append(result.toString());
else
output->append(trace->get());