用 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 ,這就不說明了。


沒有留言:
張貼留言