用 JavaScript 裡綁定類別
前言
在之前的 用 JavaScript 控制 Widget 裡使用了 Qt 的 Widget 在 JavaScript 中,如果要在 JavaScript 裡使用自己設計的類別有可能嗎?答案是可以的,要如何做呢?在此把學習的過程作紀錄。
內容
先到 [ GitLab ] HelloQt 下載範例,這次應用的專案路徑
(HelloQt' directory)/JSEngine/WrapClass,執行結果如下
範例的執行結果 |
範例的上方會有預設的程式碼,按下右下的"Run"可以執行,執行預設的程式碼看列印的偵錯訊息。
要在 JavaScript 綁定自己的類別,該類別必須繼承 QObject ,這很重要!利用 Qt Creator 的精靈產生類別的話,如下圖
使用精靈產生繼承 QObject 的類別 |
在精靈的"Class name"填上類別名稱,在"Base class"選擇 QObject 後即可,範例已產生"MyClass",所以看到"MyClass"的宣告,如下
#include <QObject> class MyClass : public QObject { Q_OBJECT Q_PROPERTY(int dataInt READ myInt WRITE setMyInt) Q_PROPERTY(double dataDouble READ myDouble WRITE setMyDouble) Q_PROPERTY(QString dataString READ myString WRITE setMyString) public: explicit MyClass(QObject *parent = nullptr); // void setMyInt( int value ); int myInt() const; void setMyDouble( double value ); double myDouble() const; void setMyString( const QString& value ); QString myString() const; Q_INVOKABLE void callMethod(); signals: private: int m_MyInt; double m_MyDouble; QString m_MyString; };
MyClass 會綁定三個 Property ,"m_MyInt"、"m_MyDouble"與"m_MyString",並綁定一個 Function 名為"callMethod",綁定 Function 到 JavaScript 的部分比較簡單,只需再開頭加"Q_INVOKABLE"即可,但要注意輸入的引數與回傳值得資料型態必須是 JavaScript 可以接受的型態,至於那些型態可以接受以後來研究,這次都先使用基本的型態。在綁定 Property 的部份就比較麻煩一些,綁定些要用到"Q_PROPERTY"來綁定,後方的內容要照一定的格式寫,就拿 m_MyInt 來說,"int"是綁定到 JavaScript 的型態,這個型態最後會被自動轉成 JavaScript 的 "Number" ,"dataInt" 是 Property 的名稱,可以自己命名,不一定要和 C++ 這邊的變數同名,"READ myInt"指的是讀取時所喚起的 Function ,在這裡會喚起 myInt() ,接著是"WRITE setMyInt"指的是寫的時候所喚起的 Function ,這裡會喚起 setMyInt() 。在讀與寫的 Function 也要注意資料型態的問題,字串的部份要用 QString 來綁定而非 std::string, MyClass 的實作部分沒什麼好說明就直接略過,接著看到 MainWindow::MainWindow() ,如下
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // connect( ui->runButton , &QPushButton::clicked , this , &MainWindow::onRunButtonClicked ); // m_cJSEngine.installExtensions( QJSEngine::ConsoleExtension ); // MyClass* pMyClass = new MyClass(); m_cJSEngine.globalObject().setProperty( "myClass" ,m_cJSEngine.newQObject( pMyClass ) ); // ui->textEdit->setText( tr( "console.log( myClass.dataInt );\n"\ "console.log( myClass.dataDouble );\n"\ "console.log( myClass.dataString );\n"\ "myClass.dataInt = 5678;\n"\ "myClass.dataDouble = 1.414;\n"\ "myClass.dataString = 'My string';\n"\ "console.log( myClass.dataInt );\n"\ "console.log( myClass.dataDouble );\n"\ "console.log( myClass.dataString );\n"\ "myClass.callMethod();\n"\ ) ); }
程式開頭依舊初始化與綁定事件,這次就不說明了,接著直接 New 一個 MyClass ,透過 QJSEngine::newQObject() 來新增變數,就像上次在 用 JavaScript 控制 Widget 裡做的一樣,就著就是寫下預設的 JavaScript 程式碼,單純列印變數與喚起 Method ,這就不說明了。
沒有留言:
張貼留言