QT開發(五十一)——QtQuick基礎
一、QtQuick簡介
QT提供了兩種獨立的方法創建用戶界面。
QtQuick模塊爲創建流暢、鮮活的用戶界面提供了一種標記語言。QtQuick模塊適合需要動畫元素的界面,以及應用程序主要運行在小屏幕和多點觸控的設備上的場景。
QtWidgets模塊針對傳統桌面提供了更多的支持,和目標平臺做了更多的集成,無論目標平臺是MacOSX、Windows、KDE、GNome。QtWidgets是一個非常高效的基於C++的類庫,包含很多常見的用戶界面組件,可以非常容易地爲這些已存在的組件擴展新的功能。
QtQuick模塊是使用QML語言編寫應用程序的標準庫。Qt QML模塊提供了QML引擎和語言架構,QtQuick模塊提供了使用QML語言創建用戶界面的所有基礎類型。
QtQuick模塊提供了兩套接口,QML API提供了使用QML語言創建用戶界面的QML類型,C++ API提供了使用C++代碼擴展QML應用程序接口。
QT4.7開始引入了QML,QML(Qt Meta-Object Language,Qt元對象語言)是一種用於描述應用程序用戶界面的聲明式編程語言。QML使用一些可視組件以及這些組件之間的交互來描述用戶界面,是一種高可讀性的語言,可以使組件以動態方式進行交互,並且允許組件在用戶界面中很容易地實現複用和自定義。QML允許開發者和設計者以類似的方式創建高性能的、具有流暢的動畫效果的、極具視覺吸引力的應用程序。QML提供了一個具有高可讀性的類似JSON的聲明式語法,並提供了必要的 JavaScript語句和動態屬性綁定的支持。
二、 Qt Quick工程實例
1、創建Qt Quick應用
選擇Qt Quick Application。
工程創建好後,Qt Quick工程包含QML文件、源文件、
2、QML文件
Main.qml文件:
import QtQuick 2.6 import QtQuick.Window 2.2 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") MainForm { anchors.fill: parent mouseArea.onClicked: { Qt.quit(); } } }
QML文檔定義了一個QML對象樹,由兩部分組成:一個import導入部分,一個對象聲明部分。
import導入語句類似於C++中的#include,只有導入了相關模塊,才能使用其中的類型和功能。導入的模塊QtQuick模塊是在創建項目時選擇的組件集,包含了創建用戶界面所需要的基本類型和功能,QtQuick.Window模塊中提供了Window類型,可以爲Qt Quick場景創建一個頂層窗口。
對象聲明部分,QML文檔中的對象聲明定義了要在可視場景中顯示的內容。工程創建了兩個對象:Window對象和其子對象MainForm。對象(object)由它們的類型(type)指定,以大寫字母開頭,後面跟隨一對大括號,在括號中包含了對象的特性定義,比如對象的屬性值或者其子對象。最外層的對象叫根對象,比如Window,在根對象裏面定義的對象,叫做根對象的子對象,比如MainForm就是Window的子對象。 在Window中的visible是Window的屬性,用來設置窗口是否顯示,可以在幫助文檔中查看一個類型的所有屬性及用法。
MainForm不是QtQuick模塊中的類型,而是自定義的一個用戶界面表單(Qt Quick UI Forms),是Qt 5.4後提出的一個概念,類似於Qt C++編程中的UI文件,MainForm.ui.qml文件只能在設計模式下編輯。
import QtQuick 2.6 Rectangle { property alias mouseArea: mouseArea width: 360 height: 360 MouseArea { id: mouseArea anchors.fill: parent } Text { anchors.centerIn: parent text: "Hello World" } }
在main.qml文件中,MainForm就是MainForm.ui.qml的一個實例,而MainForm內部調用了mouseArea屬性的onClicked事件處理器,相當於調用了MainForm.ui.qml中的MouseArea對象的onClicked事件處理器,Qt.quit()表明當在整個矩形中點擊鼠標時要執行的命令就是退出程序。
所有的QML文件是以資源的形式放在.qrc文件中的,QML文件不需要編譯,類似於素材。
3、源文件
Main.cpp文件:
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
main函數中定義了一個QQmlApplicationEngine對象,並用其加載了main.qml文件。QQmlApplicationEngine類結合了QQmlEngine和QQmlComponent兩個類的功能,提供了一個便捷的方式來加載一個QML文件,但QML文件的所有可視內容必須放在Window對象中才能最終顯示出來。
4、pri工程附屬文件
Deployment.pri文件:
unix:!android { isEmpty(target.path) { qnx { target.path = /tmp/$${TARGET}/bin } else { target.path = /opt/$${TARGET}/bin } export(target.path) } INSTALLS += target } export(INSTALLS)
5、創建QML文件
要在工程中創建QML文件,創建QML文件的QML模板可以選擇Qt Quick 1、Qt Quick 2和QtQuickUI File三種,Qt Quick 1會導入QtQuick 1.1模塊,適用於Qt 4版本;QtQuick 2導入QtQuick 2.0模塊,適用於Qt 5版本;QtQuick UI文件生成後會默認使用設計器。
QML文件不需要進行編譯,可以直接運行。Qt提供了兩個運行QML文件的工具qmlviewer和qmlscene,前者是Qt 4時代的產物,主要用來顯示導入了QtQuick 1.1模塊的QML文件,而qmlscene用來顯示導入了QtQuick 2.0後版本的QML文件。選擇“工具→外部→QtQuick→Qt Quick 2Preview”菜單項即可在qmlscene中顯示現在打開的QML文檔的內容。
三、擴展QML程序
1、添加文本顯示
import QtQuick 2.0 Rectangle { width: 100 height: 62 Text { text: "hello World" } }
Text對象用來顯示一塊文本,其text屬性用來指定要顯示的文本內容
2、錨佈局
QML中每一個組件都有一組無形的錨,分別在上、下、左、右、中心等處,可以定義組件自身和其他組件的相對位置。centerIn指Text組件在parent組件的中心,parent指Text的父組件Rectangle。
import QtQuick 2.0 Rectangle { width: 100 height: 62 Text { anchors.centerIn: parent text: "hello World" } }
3、鼠標互動
import QtQuick 2.0 Rectangle { width: 100 height: 62 Text { anchors.centerIn: parent text: "hello World" } MouseArea { anchors.fill: parent onClicked: { Qt.quit() } } }
MouseArea子對象是鼠標區域,是一個不可見的組件,通過MouseArea對象可以實現鼠標互動。anchors.fill是進行填充,將鼠標區域覆蓋整個Rectangle窗口。onClicked是Qt C++中的信號處理函數,即信號處理器,其語法是on<Signal>,onClicked是Clicked單擊信號的處理,當在窗口上單擊鼠標後會執行Qt.quit()全局函數,執行結果就是退出程序。
4、id屬性和屬性別名
id屬性是一個對象的名字,來唯一確定一個對象,在其他對象中可以通過id引用該對象。
import QtQuick 2.0 Rectangle { width: 100 height: 62 property alias mArea:mouseArea Text { anchors.centerIn: parent text: "hello World" } MouseArea { id:mouseArea anchors.fill: parent } }
MouseArea對象,設置其id爲mouseArea,在Rectangle中可以通過mouseArea來訪問MouseArea對象。在其他QML文件訪問Rectangle內的子對象,需要在Rectangle中自定義屬性,並且該屬性需要是子對象的屬性別名,例如聲明的mArea屬性,alias表明mArea是mouseArea的別名。
mArea.onClicked: { Qt.quit() }