找了半天關于QtScript的中文文檔很少,隻能檢視英文文檔,順便翻譯一下。
Qt對基于ECMAScript的腳本提供了支援,下面的指導和參考涵蓋了ECMAScript和Qt的各個方面。
腳本類
下面的類将腳本的功能添加到Qt應用程式當中。
QScriptClass 用于定義自定義的Qt腳本對象的接口
QScriptClassPropertyIterator 用于周遊自定義腳本對象的接口
QScriptContext 一個Qt腳本函數的調用上下文
QScriptContextInfo 關于QScriptContext的額外資訊
QScriptEngine 執行Qt腳本代碼的環境
QScriptEngineAgent QScriptEngine執行相關事件的接口
QScriptEngineDebugger QScriptEngine調試環境
QScriptProgram 封裝了Qt腳本程式
QScriptString 表示QScriptEngine中字元串的句柄??
QScriptSyntaxCheckResult 存儲腳本文法檢查的結果
QScriptValue 表示Qt腳本資料類型的容器
QScriptValueIterator QScriptValue周遊器
QScriptable QtC++程式通路Qt腳本環境
語言概述
Qt腳本基于ECMAScript腳本語言,使用ECMA-262标準。微軟的JScript和網景的javascript也是基于ECMAScript标準,有關 ECMAScript的概述,可以檢視ECMAScript标準。如果你不熟悉ECMAScript語言,有一些指導和書籍,例如JavaScript: The Definitive Guide.
基本用法
為執行腳本代碼,你可以建立一個QScriptEngine,然後調用它的evaluate()方法,傳入腳本代碼作為evaluate()的參數。
QScriptEngine engine;
qDebug() << "the magic number is:" << engine.evaluate("1 + 2").toNumber();
傳回值是evaluate()執行的結果,這個結果可以轉換為标準C++和Qt類型。
通過設定腳本引擎的全局對象,将自定義屬性注冊到腳本引擎當中變的很容易。
engine.globalObject().setProperty("foo", 123);
qDebug() << "foo times two is:" << engine.evaluate("foo * 2").toNumber();
以上代碼是将屬性放到腳本引擎當中,這樣的腳本代碼是有效的。
使QObject對象在QScript Engine中有效
在腳本當中任何基于QObject執行個體是有效的。
将QObject對象傳入QScriptEngine::newQObject()函數當中,這樣Qt腳本的封裝基于QObject的對象将會被建立,被建立的腳 本對象可以使用QObject的信号、槽、屬性、和子對象清單。
下面是一個Qobject子類化的例子,該對象在腳本代碼中的名字是"myObject"。
QScriptEngine engine;
QObject *someObject = new MyObject;
QScriptValue objectValue = engine.newQObject(someObject);
engine.globalObject().setProperty("myObject", objectValue);
上面的例子,在腳本環境中建立一個全局的"myObject"變量,這個變量是一個c++對象的代理。C++對象在腳本中可以用任何的名稱代指,不依賴上面的QObject::objectName().
newQObject()函數接收兩個額外的可選參數:一個是所有權模式,另一個是可選的允許你控制QScriptValue封裝QObject的行為的容器,我們以後再回顧這些參數。
使用信号和槽
Qt腳本适用Qt核心的信号和槽特性,在Qt腳本當中有三種主要方式使用信号和槽。
-
混合C++/Script:C++應用程式代碼連接配接信号到一個腳本函數,例如,腳本函數可以使使用者打字輸入或者從檔案讀入的。如果你有一個QObject但是不想導出這個對象到腳本環境當中,隻是想腳本中定義怎樣響應
一個信号,并且把在c++中建立連接配接。
- 混合Script/C++: 對于應用程式導出到腳本環境中的對象,腳本能在該對象上建立信号和槽的連接配接,在這種情況下,槽仍然寫在C++端,但是連接配接完全是腳本動态定義的。
- 完全腳本定義:腳本即能定義信号處理函數(相當于在Qt腳本中定義槽),也能設定這些處理程式的連接配接,例如,腳本能定義處理QLineEdit::returnPressed()信号的函數, 然後連接配接信号與這個腳本處理函數。
用qScriptConnect()函數連接配接c++信号與腳本函數,下面的例子是定義了一個連接配接到QLineEdit::textChanged()信号的腳本處理函數:
QLineEdit *edit1 = new QLineEdit(...);
QLineEdit *edit2 = new QLineEdit(...);
QScriptValue handler = eng.evaluate("(function() { print('I am', this.name); })");
QScriptValue obj1 = eng.newObject();
obj1.setProperty("name", "the walrus");
QScriptValue obj2 = eng.newObject();
obj2.setProperty("name", "Sam");
qScriptConnect(edit1, SIGNAL(returnPressed()), obj1, handler);
qScriptConnect(edit2, SIGNAL(returnPressed()), obj2, handler);
我們建立兩個QLineEdit對象并且定義一個簡單的信号處理函數,連接配接用同一個處理函數,處理函數根據不同的對象觸發
而使用不同的this對象調用,print()代碼段的輸出将是不同的。
在腳本代碼當中,Qt腳本用不同的句法建立和取消信号之間的連接配接,而不是像C++句法那樣隻是用QObject::connnect()。您将相關信号引用為發送器對象的屬性,并調用其connect()。有三個connect()的重載,每個都有一個相應的disconnect()過載。下面的小節描述了這三種形式。
- 函數連接配接的是信号(信号連接配接信号)
connect(function)
這種連接配接情況下,connect()的參數是連接配接到信号的處理函數
function myInterestingScriptFunction() {
// ...
}
// ...
myQObject.somethingChanged.connect(myInterestingScriptFunction);
參數可以是腳本函數,例如上面的例子。也可以是一個QObject對象的slot函數,像下面的例子:
myQObject.somethingChanged.connect(myOtherQObject.doSomething);
當參數是一個QObject對象的slot函數時,信号和槽的參數類型可以不相容。如果必要,Qt Script将執行信号參數的轉換,以比對時隙的參數類型。
取消信号的連接配接,你可以調用這個信号的disconnect()函數,傳遞取消連接配接的參數:
myQObject.somethingChanged.disconnect(myInterestingFunction);
myQObject.somethingChanged.disconnect(myOtherQObject.doSomething)
當connect()隻有一個參數時,this對象将是 Global Object。
- 信号連接配接到成員函數
connect(thisObject, function)
在這種連接配接方式下,第一個參數是綁定到this變量,第二個參數是被調用的函數。
在這種方式下,如果你有一個push button,你通常想在button的點選信号觸發是做一些事情,在這種情況下,作為該對象傳遞窗體是有意義的。
var obj = { x: 123 };
var fun = function() { print(this.x); };
myQObject.somethingChanged.connect(obj, fun);
取消信号的連接配接,将同樣的參數傳遞到disconnect()中:
myQObject.somethingChanged.disconnect(obj, fun);
- 命名成員函數連接配接的信号
connect(thisObject, functionName)
在這種連接配接方式下,第一個參數是綁定到this的變量,當信号的響應函數是被調用的,第二個參數指定信号的處理函數,這種情況下涉及到處理函數是第一個參數的成員函數。
注意這種情況下處理函數在連接配接時已經被确定了,而不是在信号觸發是動态決定的。
var obj = { x: 123, fun: function() { print(this.x); } };
myQObject.somethingChanged.connect(obj, "fun");
取消信号連接配接用同樣的參數 傳遞到disconnect() 中:
myQObject.somethingChanged.disconnect(obj, "fun");