2020年9月15日 星期二

在 Qt 環境使用 JavaScript

在 Qt 環境使用 JavaScript

前言

  Qt 提供使用 JavaScript 的環境,但需要經過一些設定才能使用,為了怕日後忘記怎麼設定,在此作個紀錄。

內容

  先到 [ GitLab ] HelloQt 下載範例,這次應用的專案路徑
(HelloQt' directory)/JSEngine/Basic,執行結果如下
範例的執行結果

範例的輸入對話框可以輸入 JavaScript 的程式碼,按下右下的"Run"按鈕執行程式。在開始看程式碼之前要先看到專案檔,在開頭可以看到以下
QT       += core gui qml

紅字的部分是要自己加的,這就是使用 JavaScript 的前置作業。

  看到程式碼宣告的部分,如下
#include <QMainWindow>
//
#include <QJSEngine>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

protected slots:
  void onPushButtonClicked(bool clicked);
private:
  Ui::MainWindow *ui;
  //
  QJSEngine m_cJSEngine;
};

Qt 要使用 JavaScript 是透過 QJSEngine 這個類別來處理,也就是成員"m_cJSEngine",在使用這個類別需要先 include "QJSEngine"。範例會需要使用到  TextEdit ,如果不熟悉如何使用可以參考 TextEdit 的基本應用。接著就看到實作的部分,看到 MainWindow::MainWindow() ,程式碼如下
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  //
  connect( ui->pushButton , &QPushButton::clicked , this , &MainWindow::onPushButtonClicked );
  //
  m_cJSEngine.installExtensions( QJSEngine::ConsoleExtension );
  //
  ui->textEdit->setText( tr("console.log('Hello world')") );
}

開頭先綁定"Run"按鈕的事件,接著會喚起 QJSEngine::installExtensions() ,這行可以讓 QJSEngine 支援 console 相關的 Funciton ,最後是設定 TextEdit 給予預設的程式碼,接著來看按鈕事件的程式碼,如下
void MainWindow::onPushButtonClicked(bool clicked)
{
  QJSValue result = m_cJSEngine.evaluate( ui->textEdit->toPlainText() );
  if( result.isError() )
  {
    //
    QJSValue errorStr = result.property( tr("stack") );
    //Filter format string "stack:@:"
    QString errorLine = errorStr.toString().mid(8);
    //
    qDebug( "Error at line(%s) %s" , errorLine.toLocal8Bit().data() ,result.toString().toLocal8Bit().data() );
  }

}

開頭會透過 QJSEngine::evaluate() 來執行結果,引數是目前 TextEdit 的內容,這就幾乎等同在 JavaScript 裡喚起 eval() ,看到回傳的"result",類別為 QJSValue ,其實就 JavaScript 的變數,範例透過喚起 QJSValue::isError() 來確定是否發生 Exception ,接著取出"stack"這個 Property 
,取出來的變數類別依舊是 QJSValue ,這個變數會用來取得當 Exception 發生的行數,但他有一點不完美,它的內容是一個格式的文字,所以透過 mid() 來過濾掉開頭的格式文字,最後過濾完的行樹就會存在"errorLine",最後顯示偵錯訊息的部分,行數是"errorLine",而錯誤的訊息就直接存在"result",所以透過 QJSValue::toString() 就可以把錯誤訊息拿出來。

參考資料


相關文章與資料

沒有留言:

張貼留言