【问题标题】:QJSEngine: print to consoleQJSEngine:打印到控制台
【发布时间】:2015-08-16 21:26:51
【问题描述】:

我正在从QScriptEngine(已弃用)转移到QJSEngine,我发现我无法使用print

  QJSEngine engine;

  QJSValue val = engine.evaluate(
        "print('123');"
        );

  if (val.isError()){
     qDebug() << "error: " << val.toString();
  }

  qDebug() << "val: " << val.toVariant();

输出是:

error:  "ReferenceError: print is not defined"

QScriptEngine 中有效。

那么,在QJSEngine 中打印到控制台的方法是什么?在文档中找不到任何内容。我尝试使用console.log,但也没有定义console

【问题讨论】:

    标签: qt console.log qjsengine


    【解决方案1】:

    从 Qt 5.6 开始,解决方案更加简单:可以安装 Javascript 扩展。一个这样的扩展是提供print 功能的控制台:

    QJSEngine myEngine;
    myEngine.installExtensions(QJSEngine::ConsoleExtension);
    myEngine.eval("print(1 + 2)");
    

    【讨论】:

      【解决方案2】:

      QJSEngine 没有实现打印功能。您必须自己实现它。幸运的是,您可以编写 QObjects 并使它们在您的脚本中可用。 (参见http://doc.qt.io/qt-5/qjsengine.html 的“QObject 集成”部分)

      这是我的做法:

      创建一个继承自 QObject 的类 JSConsole:

      你自己的控制台类

      jsconsole.h

      #ifndef JSCONSOLE_H
      #define JSCONSOLE_H
      
      #include <QObject>
      
      class JSConsole : public QObject
      {
          Q_OBJECT
      public:
          explicit JSConsole(QObject *parent = 0);
      
      signals:
      
      public slots:
          void log(QString msg);
      };
      
      #endif // JSCONSOLE_H
      

      jsconsole.cpp

      #include "jsconsole.h"
      #include <QDebug>
      
      
      JSConsole::JSConsole(QObject *parent) :
          QObject(parent)
      {
      }
      
      void JSConsole::log(QString msg)
      {
          qDebug() << "jsConsole: "<< msg;
      }
      

      使用它

      现在你使用 QJSEngine.newQObject 在 js 引擎中创建一个代理对象。 之后,将其添加到全局对象并使用它。

      QJSEngine engine;
      JSConsole console;
      QJSValue consoleObj =  engine.newQObject(&console);
      engine.globalObject().setProperty("console", consoleObj);
      QJSValue result = engine.evaluate("console.log('test');");
      

      错误记录

      当我刚刚在我的 js 文件中出现拼写错误时,我已经在我的 c++ 代码中搜索了很长时间。以下 sn-p 将有助于避免这种情况。

      if (result.isError())
      {
          qDebug() << "result: " << result.property("lineNumber").toInt() << ":" << result.toString();
      }
      

      PS:潜伏多年后的第一篇文章。我已阅读编写出色答案的技巧,但如果我犯了一些错误/不好的事情,请告诉我。

      愿代码与你同在

      【讨论】:

      • 编辑:据我了解,要让脚本中的方法可用,您必须将它们定义为 slots
      • 如果脚本中方法的可用性是使它们成为插槽的唯一原因,那么最好使用宏Q_INVOKABLE 来声明它们:它会更清楚地显示程序员的意图。感谢你的回答。欢迎来到 SO。
      • 这真的很有帮助。很少有关于这个的文档(以及一般的 QJS 引擎)
      猜你喜欢
      • 2016-09-21
      • 1970-01-01
      • 2016-11-26
      • 2012-02-07
      • 2015-05-04
      • 2016-11-19
      • 2018-07-14
      • 2013-03-29
      • 2020-09-29
      相关资源
      最近更新 更多