QtQuick 可使用內置的 JavaScript 引擎加載相應的 JS 代碼,使用起來特別方便。c++
在 Qt 中使用 C++ 開發底層,QtQuick 用來加載、處理圖像,而後使用 Qt 提供的接口保證二者可以正常通訊便可。git
1. 首先用Qt Creator新建項目,選擇Qt Quick Controls 2 Application,命名項目…github
2. 在資源文件qml.qrc中添加一個qml文件,命名…app
3. 在qml文件中輸入相應的元素(Item,Rectanger,Image,Canvas等等)。函數
1 import QtQuick 2.0 2 import QtQuick.Window 2.2 3 4 Window { 5 width: 800 6 height: 600 7 visible: true 8 title: "Test window" 9 }
這裏僅用了一個 Window 元素,加載後只顯示一個空白的窗體。ui
4. 在main函數中加載qml引擎須要用到QQmlApplicationEngine類,經過該類加載qml文件。以下:this
1 int main(int argc, char *argv[]) 2 { 3 QGuiApplication app(argc, argv); 4 5 QQmlApplicationEngine engine; 6 engine.load(QUrl(QStringLiteral("qrc:/Test.qml"))); 7 8 return app.exec(); 9 }
其中,engine 對象的 load() 方法,須要一個QUrl對象提供qml文件的url路徑,這裏加載了一個qml文件,即「Test.qml」文件。url
運行以後獲得空白的窗體。若是想要顯示不一樣的內容,須要在qml文件中添加相應的元素或本身編寫控件再添加。spa
用 QQmlApplicationEngine 加載的 qml 文件可使用 QML 的 Window 控件。指針
可是在c++ 的類方法中沒法直接使用 QQmlApplicationEngine 類,若使用該類加載 qml 文件,會致使在觸發顯示窗口事件時,窗口顯示一下當即消失,可是程序依然在運行,所以就沒法對qml窗口進行操做。
1 void Data::view() { 2 QQmlApplicationEngine engine; 3 engine.load(QUrl(QStringLiteral("qrc:/Test.qml"))); 4 }
在Data類的view()方法中使用 QQmlApplicationEngine load() 方法沒法正常顯示窗口。
那麼,如何在方法中調用加載 qml 文件呢?
要在 c++ 文件中顯示qml文件的內容,Qt 提供了 QQuickView 類(QtQuick1.0則是使用 QDeclaritiveView 類,可是該類在加載 qml 文件時,響應緩慢)使用 QQuickView 便可加載 qml 並顯示內容。
1 void Data::view() { 2 QQuickView *compassview = new QQuickView; 3 compassview->setSource(QUrl(QStringLiteral("qrc:/Compass.qml"))); 4 // compassview->rootContext()->setContextProperty("dataRadius", this); 5 QQmlContext *context = compassview->rootContext(); 6 context->setContextProperty("dataSource", this); 7 // 設置窗口圖標 8 QIcon icon = QIcon(QStringLiteral(":/img/compass.ico")); 9 compassview->setIcon(icon); 10 // compassview->set 11 // 設置窗口縮放時,根對象也會隨之縮放 12 compassview->setResizeMode(QQuickView::SizeRootObjectToView); 13 compassview->setTitle("Compass heading pitch & roll"); 14 compassview->show(); 15 16 }
compassview 指向一個 QQuickView 對象,setSource() 方法指定該 QQuickView 對象所要加載的qml文件。
而 compassview->rootContext() 則是獲取對象的根元素上下文,而後用 context 對象的 setContextProperty(const QString *, const QVariant*) 方法設定上下文屬性,便可經過 QVariant 指針從 C++ 向 QML 傳遞數據。
然而若是qml文件是以 Window 做爲根元素的話,QQuickView加載時會出現一個警告,由於QQuickView繼承自QQuickWindow(又繼承自QWindow),它自己就是一個窗口類,若是再用 QML 的 Window 控件做爲根元素,天然會出現警告,能夠忽略掉該警告,也能夠將 Window 改爲 Item (但要注意,Window 的有些屬性在 Item 中不存在),這樣就不會出現警告了。
而後在 qml 文件中經過設定一個定時器 Timer,能夠定時從 c++ 中獲取數據。
1 /* 2 * 設置一個定時器,每隔 500ms 就從數據源中讀取數據,修正圖像 3 */ 4 Timer { 5 id: updateTimer 6 interval: 500 7 running: true 8 repeat: true 9 10 onTriggered: { 11 // console.log("Timer is triggered! ") 12 // var data = DataSource.getData(); 13 var data = dataSource.getRadius() 14 15 data = [0, 0, 0] 16 // h_refresh(data[0]) 17 refresh(data[0], data[1], data[2]) 18 } 19 }
qml中 dataSource 須要與上面的 setContextProperty(「dataSource」, this) 語句中的 dataSource 同名(這樣就能夠直接調用相關對象的方法,好比 getRadius() 方法),不然 qml 將沒法獲取數據。
C++ 中設置 QQuickView 的窗口圖標、標題等等與 QWindow 相似。
compassview->setResizeMode(QQuickView::SizeRootObjectToView) 設置了根對象大小隨窗口大小改變而改變。這樣就能動態縮放qml內容。
--------------------------------------------------------------------------------
另外須要注意的是,若是先用 Qt 新建了一個 Qt 應用,想要再添加 qml 文件並運行,須要修改項目的 .pro 文件,添加如下內容:
QT += qml quick
這樣,在編譯時纔不會出錯。
====================================================
另外,附上完整的代碼