首先推薦幾篇博客html
1.深刻解析QML引擎, 第1部分:QML文件加載c++
http://www.javashuo.com/article/p-kgsogsfm-he.html函數
2.深刻解析QML引擎, 第2部分: 綁定(Bindings)spa
http://www.javashuo.com/article/p-prcuqsrt-gw.html翻譯
3.深刻解析QML引擎, 第3部分: 綁定類型code
http://www.javashuo.com/article/p-ughcreej-gs.htmlhtm
4.深刻解析QML引擎, 第4部分: 自定義解析器對象
http://www.javashuo.com/article/p-acfvagie-ha.htmlblog
5.QML引擎的演進,第一部分繼承
https://blog.qt.io/cn/2013/04/18/evolution-of-the-qml-engine-part-1/
這四篇博文由淺入深的講述了QML引擎的實現機制。
1.QML文件的加載過程涉及到QML文件的解析,js代碼的解釋;
2.綁定講解了QML的屬性綁定,經過VME模塊建立的指令.生成一個QQmlBinding對象,傳入js函數,vme再把傳入的函數生成一個v8:Function函數(翻譯成二進制的機器碼)。經過運行編譯後的V8::Function代碼來對綁定進行求值,再由V8引擎經過Qt裏的包裹類來訪問對象和屬性,而後將求的值賦給目標屬性。
3.由於QV8Bindings把QML文件中全部的綁定組織在一塊兒,因此能夠花費更少的內存,並只執行一次編譯。
概括起來,有3個綁定類型,都是從QQmlAbstractBinding繼承:
1). QV4Bindings::Binding
2). QV8Bindings::Binding
3). QQmlBinding
QV4Bindings是最快的,由於其使用了自定義的字節碼引擎。QV8Bindings和QQmlBinding都是使用V8 JS引擎執行,但QV8Bindings將全部的綁定組織在一塊兒,一次性編譯,然而QQmlBindings會在每一個QML組件實例化過程當中一個一個地進行編譯。
4.多個對象模型
當前的QML引擎使用V8 JavaScript引擎來執行屬性綁定。每一個QML項內部有幾個不一樣的表示。一個面向V8(使用公開的V8 API),一個面向QML引擎,還有一個做爲QObject暴露給原生Qt。這裏的問題是須要QML引擎來同步這些不一樣的表示,致使了大量的中間代碼和至關高的內存消耗來維持這些不一樣的表示。
QML調用js函數的調用堆棧以下:
QML調用C++函數的調用堆棧以下:
person類(js調用的c++函數所在的類)的函數最後的調用過程爲
void Person::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { auto *_t = static_cast<Person *>(_o); Q_UNUSED(_t) switch (_id) { case 0: _t->walk(); break; case 1: { bool _r = _t->eat((*reinterpret_cast< const QString(*)>(_a[1]))); if (_a[0]) *reinterpret_cast< bool*>(_a[0]) = std::move(_r); } break; default: ; } } }