前段時(shí)間接觸了一下QML,深深地被這門強(qiáng)大易用的語言所吸引。
QML的語法類似CSS,可以引入javascript作為邏輯,還能夠和C++對(duì)象交互。
QML帶來的好處至少有以下幾點(diǎn):
- 分工更明確:設(shè)計(jì)師可以專攻QML制作UI,C++工程師也能專注于自己的本職工作。
- 開發(fā)更高效:重新編寫的QML不需要編譯(因?yàn)樗且婚T腳本語言),所以只需要刷新一下你的QML Viewer就可以了。
- 界面更精美:QML開發(fā)和網(wǎng)頁開發(fā)很相似,所以我們可以比較容易地把一個(gè)精美的網(wǎng)頁效果移植到本地程序。
- 風(fēng)格更一致:Qt本身是一個(gè)跨平臺(tái)的開發(fā)框架,所以我們?cè)赪indow XP上看到的是一個(gè)樣子,Win7上看到的是另一個(gè)樣子,到了Ubuntu或者M(jìn)ac更是變了模樣,使用QML可以屏蔽這些不一致。
下面帶來一個(gè)簡單的示例,希望對(duì)讀者們有幫助。
谷歌桌面相信很多人都用過,雙擊ctrl可以呼出一個(gè)浮動(dòng)的搜索框,非常方便。我們將使用QML仿制這一效果。先看效果圖:
怎么樣?很炫吧~
好的,首先打開你的Qt Creator(QML是Qt4.7以后才有的特性,請(qǐng)升級(jí)你的SDK到最新版本 )。然后新建一個(gè)項(xiàng)目。接著新建一個(gè)C++ Class,命名為FloatBox?,F(xiàn)在你的工程的目錄結(jié)構(gòu)應(yīng)該像這樣:
接著,再新建一個(gè)QML文件:

我們將這個(gè)QML文件命名為TextBox。這個(gè)QML文件主要是實(shí)現(xiàn)搜索框中的文本框。
輸入以下代碼:
- import Qt 4.7
-
- FocusScope {
- id: focusScope
- width: 600; height: 40
- focus:true
-
- BorderImage {
- source: "../images/lineedit-bg.png"
- width: parent.width; height: parent.height
- border { left: 4; top: 4; right: 4; bottom: 4 }
- }
-
- Text {
- id: typeSomething
- anchors.fill: parent; anchors.leftMargin: 8
- verticalAlignment: Text.AlignVCenter
- text: "\u8BF7\u8F93\u5165\u7F51\u5740"
- color: "gray"
- }
-
- MouseArea {
- anchors.fill: parent
- onClicked: { focusScope.focus = true; textInput.openSoftwareInputPanel(); }
- }
-
- TextInput {
- id: textInput
- anchors { left: parent.left; leftMargin: 8; right: clear.left; rightMargin: 8; verticalCenter: parent.verticalCenter }
- focus: true
- font.pixelSize:20
- }
-
- Image {
- id: clear
- anchors { right: parent.right; rightMargin: 8; verticalCenter: parent.verticalCenter }
- source: "../images/clear.png"
- opacity: 0
-
- MouseArea {
- anchors.fill: parent
- onClicked: { textInput.text = ''; focusScope.focus = true; textInput.openSoftwareInputPanel(); }
- }
- }
-
- states: State {
- name: "hasText"; when: textInput.text != ''
- PropertyChanges { target: typeSomething; opacity: 0 }
- PropertyChanges { target: clear; opacity: 1 }
- }
-
- transitions: [
- Transition {
- from: ""; to: "hasText"
- NumberAnimation { exclude: typeSomething; properties: "opacity" }
- },
- Transition {
- from: "hasText"; to: ""
- NumberAnimation { properties: "opacity" }
- }
- ]
- }
你也許會(huì)注意到,在Text的text屬性中,我輸入的是utf編碼的漢字。事實(shí)上,想要在QML文件里顯示中文還是有一點(diǎn)小麻煩的,要么就是用utf編碼過的漢字,要么使用Qt翻譯家來轉(zhuǎn)換。直接在QML中輸入中文將無法顯示。
接著,新建ShadowRectangle文件。該文件實(shí)現(xiàn)的是陰影效果。代碼如下:
- import Qt 4.7
-
- Item {
- property alias color : rectangle.color
-
- BorderImage {
- anchors.fill: rectangle
- anchors { leftMargin: 0; topMargin: 0; rightMargin: -8; bottomMargin: -8 }
- border { left: 10; top: 10; right: 10; bottom: 10 }
- source: "../images/shadow.png"; smooth: true
- }
-
- Rectangle { id: rectangle; anchors.fill: parent; radius:5}
- }
最后新建main.qml文件,該文件實(shí)現(xiàn)的是整個(gè)搜索欄的效果。其代碼如下:
- import Qt 4.7
-
- Rectangle {
- id: page
- width: 614; height: 54
- color: "#7bffffff"
- radius:5
-
- MouseArea {
- anchors.fill: parent
- onClicked: page.focus = false;
- }
- ShadowRectangle {
- color: "#434343"
- transformOrigin: "Center"
- opacity: 0.97
- visible: true
- anchors.centerIn: parent; width: 610; height: 50
- }
- TextBox {
- id: search;
- visible: true
- opacity: 1
- anchors.centerIn: parent
- }
- }
QML的代碼通俗易懂,這里就不去解釋每一行代碼的意思了。
好的,下面讓我們把QML制作的搜索欄放置到桌面程序的窗體上。
在你的floatbox.h中添加一個(gè)私有變量:
- private:
- QDeclarativeView *ui;
然后在你的floatbox.cpp的構(gòu)造函數(shù)中輸入以下代碼:
-
- setWindowFlags(Qt::FramelessWindowHint);
- setAttribute(Qt::WA_TranslucentBackground, true);
- setStyleSheet("background:transparent;");
-
- ui = new QDeclarativeView;
- ui->setSource(QUrl("qrc:/resources/qml/main.qml"));
- setCentralWidget(ui);
- resize(QSize(630, 60));
細(xì)心的你可以發(fā)現(xiàn),我將qml文件加入了Qt的資源系統(tǒng)。這里要說明一點(diǎn),非常重要:
在QML文件中如果引入了其他文件(包括js文件、圖片文件等),要么都加入Qt的資源系統(tǒng),要么都不加入,因?yàn)镼t的資源文件無法和本地文件相互訪問。
所以,如果你也和我一樣新建了qrc文件,請(qǐng)將qml文件和圖片文件一并加入到資源系統(tǒng)中去。如下圖:

到了這一步,我們的搜索工具欄差不多要完工了,想要運(yùn)行,千萬不要忘記在pro文件添加declarative模塊。
- QT += core gui declarative
好的,現(xiàn)在你就可以按下ctrl+R欣賞一下成果了。
最后,老規(guī)矩,附上源代碼。