Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 什么';返回一个“s”是什么意思;“未定义值”;当重新定义“时”;打印();QScript引擎的函数? [背景]_Javascript_C++_Qt_Interpreter_Read Eval Print Loop - Fatal编程技术网

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());