qml基礎學習 基礎概念

1、歸納

    學習qt已有2年多的時間,從qt4.7開始使用直到如今正在使用的qt5.6,基本都在windows機器上作開發。最近有意向看了下qt的qml部分,覺着仍是挺不錯的,畢竟能夠作嵌入式移動端產品的部分,仍是值的一學。後來在網上看了一些資料,算是初步瞭解了下qml,因此想就本身學習的過程作以記錄,也方便本身理解,若是你有機會看到這篇文章,那麼我認爲你也是來學習qml的,若是你已是一個有很強qml開發經驗的老手,那麼這篇文章和接下來的qml學習系列的文章你都不用看下去了,呵呵。。。git

    關於qml的由來,我的覺着Qt的Script、Quick、QML的關係與總結講的不錯,有興趣的同窗能夠去看下。 github

    qml的學習過程我主要是以Qt 學習之路 2博客和QmlBook-In-Chinese這本書爲主,同時在作小示例的時候查閱幫助文檔。每一個人的學習方式都不太同樣,若是你有更好的辦法能夠留言。canvas

2、效果預覽

    以下有4張效果圖,分別是4個小示例,關於demo後續章節會有解說,可是都是以代碼中的註解爲主,有興趣的同窗也能夠直接下載示例程序,使用qt提供的qmlscene.exe來直接執行qml文件,或者qmlviewer.exe也能夠預覽qml文件。
windows

圖1 轉動的組件ide

圖2 紅綠燈1工具

圖3 紅綠燈2oop

圖4 GridView使用佈局

3、學習qml必備

  1. 基本元素
  2. 組件,基本元素的複合
  3. 定位器(佈局)
  4. 元素佈局,錨
  5. 輸入元素,一行和多行
  6. quick現有組件
  7. 模型和視圖
  8. Canvas元素

一、基本元素post

    QML 基本元素能夠分爲可視元素和不可視元素兩類。可視元素:ItemRectangleTextImage不可見元素:MouseArea關於MouseArea是不可見元素這一點我須要強調一下,由於上邊我提到的兩篇學習文章都沒有說清楚,圖5是qt5.7的幫助文檔截圖,從圖中咱們一眼就能看出結果,MouseArea確實是不可見元素。學習

圖5 MouseArea幫助文檔

    關於基本元素我覺着qmlbook這本書相關章節的最後一段說的頗有意思,特此說明,如圖6所示

圖6 qml顯示和交互分開

    理解這些基本元素,你能夠認爲他們是一個個被封裝好的類,並且他們有很是之多的屬性,這裏我就不介紹了,由於幫助文檔說的太清楚了。

二、組件

    組件其實就是基本元素的複合,放到一個單獨的文件,方便咱們之後重用,關於怎麼建立組件,本節的後續我會給出本身作的示例程序,代碼很簡單只是爲了說明問題

三、定位器

    定位器主要有 RowColumnGridFlow等。

四、元素佈局

    除了定位器,咱們還可使用錨(anchor)來佈局元素

五、輸入元素

    鍵盤輸入的兩個元素:TextInputTextEdit。TextInput爲一行輸入,TextEdit爲多行輸入

六、quick組件

    如表1是Qt Quick Controls 1.1 提供的組件

ApplicationWindow 對應QMainWindow,提供頂層應用程序窗口
MenuBar 對應QMenuBar,提供窗口頂部橫向的菜單欄
StatusBar 對應QStatusBar,提供狀態欄
ToolBar 對應QToolBar,提供工具欄,能夠添加ToolButton和其它組件
Action 對應QAction,提供可以綁定到導航和視圖的抽象的用戶界面動做
導航和視圖
方便用戶在一個佈局中管理和顯示其它組件
ScrollView 對應QScrollView,提供滾動視圖
SplitView 對應QSplitter,提供可拖動的分割視圖佈局
StackView 對應QStackedWidget,提供基於棧的層疊佈局
TabView 對應QTabWidget,提供帶有標籤的基於棧的層疊佈局
TableView 對應QTableWidget,提供帶有滾動條、樣式和表頭的表格
控件
控件用於表現或接受用戶輸入
BusyIndicator 提供忙等示意組件
Button 對應QPushButton,提供按鈕組件
CheckBox 對應QCheckBox,提供複選框
ComboBox 對應QComboBox,提供下拉框
GroupBox 對應QGroupBox,提供帶有標題、邊框的容器
Label 對應QLabel,提供標籤組件
ProgressBar 對應QProgressBar,提供進度條組件
RadioButton 對應QRadioButton,提供單選按鈕
Slider 對應QSlider,提供滑動組件
SpinBox 對應QSpinBox,提供微調組件
Switch 提供相似單選按鈕的開關組件
TextArea 對應QTextEdit,提供可以顯示多行文本的富文本編輯框
TextField 對應QTextLine,提供顯示單行文本的純文本編輯框
ToolButton 對應QToolButton,提供在工具欄上顯示的工具按鈕
ExclusiveGroup 提供互斥
菜單
用於構建菜單的組件
Menu 對應QMenu,提供菜單、子菜單、彈出菜單等
MenuSeparator 提供菜單分隔符
MenuItem 提供添加到菜單欄或菜單的菜單項
StatusBar 對應QStatusBar,提供狀態欄
ToolBar 對應QToolBar,提供工具欄,能夠添加ToolButton和其它組件

表1 Qt Quick Controls 1.1組件

七、模型和視圖

    模型和視圖其實屬於qml的高級使用部分了,可是爲了能早些理解qml的東西,我提早拿出一些簡單的東西,預先學習下。

八、canvas畫布

    在早些qt4時代,qml只提供了幾種基礎元素,第一小節也說明了,有不少人指望的圓角矩形,橢圓和圓,可是最終官方沒有給出具體的元素,若是是要作這些組件,那麼就須要設計師給切圖。到了qt5,官方提供了canvas畫布,這個畫布能夠實現複雜的繪圖操做,而且畫布元素是基於HTML5的畫布元素來完成的。支持畫筆,填充,漸變,文本和繪製路徑建立命令。

4、小示例

    接下里就是第二節所展現的效果圖對於代碼講解了,那我也就按照上圖展現的順序一個個講解代碼

一、基礎組件講解

    在開始示例講解以前,我先說下我本身封裝的一個小組件,代碼量不多,只爲說明問題,具體請看diamante

 1 import QtQuick 2.5
 2 
 3 // 圓角矩形框矩形框,支持點擊
 4 Rectangle {
 5     property alias text: name.text;//導出文本變量
 6     property alias textColor: name.color;//導出文本顏色
 7 
 8     id: root;
 9     width: 120;
10     height: 120;
11     radius:60;
12     antialiasing: true;
13     signal clicked();//自定義信號  外部能夠經過onClicked接收
14 
15     MouseArea
16     {
17         width: root.width;
18         height: root.height;
19 
20         onClicked:
21         {
22             //鼠標點擊時發送消息 並輸入日誌
23            root.clicked();
24             console.log("rectangle clicked");
25         }
26     }
27 
28     Text
29     {
30         id: name;
31         text: "";
32         color: "black";
33         anchors.centerIn: parent;
34     }
35 }

二、旋轉的風車,代碼裏有多種方式實現矩形旋轉,具體使用那一種就由我的喜愛了

import QtQuick 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.0

import "../contrl" //導入自定義組件模塊

Window {
    id:root;
    visible: true;
    width: 600;
    height: 400;

    //背景色窗口
    Rectangle {
        id: bg;
        color:"lightsteelblue";
        width: root.width;
        height:root.height;
    }
    //鼠標點擊背景色時中止旋轉圖形
    MouseArea {
        width: bg.width;
        height: bg.height;

        onClicked: {
            ro.pause();
        }
    }

    //自定義控件  經過import導入
    Rect
    {
        id: roundItem;
        anchors.centerIn: parent;
        //漸變填充矩形
        ConicalGradient
        {
            anchors.fill: parent
            gradient: Gradient {
                GradientStop { position: 0.0; color: "lightsteelblue" }
                GradientStop { position: 1.0; color: "blue" }
            }
        }
        //旋轉動畫1  程序剛啓動會執行 緣由未知
        //        NumberAnimation on rotation {
        //            loops:Animation.Infinite;
        //            from:0;
        //            to:360;
        //            duration: 1000;
        //        }


        //旋轉動畫2  配合wheel.rotation = 360;使用  動畫 不能循環執行
        //        Behavior on rotation {
        //            NumberAnimation {
        //                loops:Animation.Infinite;//無效
        //                duration: 1000;
        //            }
        //        }

        //旋轉動畫3  相比於動畫1  在屬性中主動指明瞭target和property
        //        NumberAnimation {
        //            id:ro;
        //            loops:Animation.Infinite;
        //            property: "rotation";
        //            target:roundItem;
        //            from:0;
        //            to:360;
        //            duration: 1000;
        //        }

        //旋轉動畫4  和動畫1是同樣的  由於RotationAnimation和NumberAnimation都是繼承自PropertyAcimation
        //所以RotationAnimation動畫能夠實現和動畫2同樣的效果,使用RotationAnimation
        //        RotationAnimation on rotation {
        //            loops: Animation.Infinite;
        //            from: 0;
        //            to: 360;
        //            duration: 1000;
        //        }

        //旋轉動畫5
        RotationAnimation {
            id:ro;
            target:roundItem;
            loops: Animation.Infinite;
            from: 0;
            to: 360;
            duration: 1000;
        }

        onClicked: {
            if (ro.paused)
            {
                ro.resume();
            }
            else
            {
                ro.start();
            }
        }
    }
}

三、紅綠燈,下述代碼紅色的的切換時經過鼠標單擊進行

  1 import QtQuick 2.0
  2 import QtQuick.Window 2.0
  3 import QtGraphicalEffects 1.0
  4 
  5 import "../contrl"
  6 
  7 Window
  8 {
  9     function dosomething()//測試script腳本運行效果
 10     {
 11         console.log("do something");
 12     }
 13 
 14     id:root;
 15     visible: true;
 16     width: 370;
 17     height: 130;
 18 
 19     Rectangle
 20     {
 22         id:rootRect;
 23         width: root.width;
 24         height:root.height;
 25         anchors.centerIn:parent;
 26 
 27         Row
 28         {
 29             id:ligheGroup;
 30             spacing: 2;
 31             states:
 32             [
 33                 State {
 34                     name: "red"
 35                //     StateChangeScript {name: "myScript"; script: dosomething(); }  //能夠正常調用
 36                     PropertyChanges {
 37                         target: redLight; color:"red";
 38                     }
 39                     PropertyChanges {
 40                         target: greenLight; color:"black";
 41                     }
 42                     PropertyChanges {
 43                         target: yellowLight; color:"black";
 44                     }
 45                 },
 46                 State {
 47                     name: "green"
 48                     PropertyChanges {
 49                         target: redLight; color:"black";
 50                     }
 51                     PropertyChanges {
 52                         target: greenLight; color:"green";
 53                     }
 54                     PropertyChanges {
 55                         target: yellowLight; color:"black";
 56                     }
 57                 },
 58                 State {
 59                     name: "yellow"
 60                     PropertyChanges {
 61                         target: redLight; color:"black";
 62                     }
 63                     PropertyChanges {
 64                         target: greenLight; color:"black";
 65                     }
 66                     PropertyChanges {
 67                         target: yellowLight; color:"yellow";
 68                     }
 69                 }
 70             ]
 71 
 72             anchors.centerIn:parent;
 73             Rect//紅燈
 74             {
 75                 id:redLight;
 76                 color:"black";
 77                 radius: width/2;
 78             }
 79             Rect//綠燈
 80             {
 81                 id:greenLight;
 82                 color:"black";
 83                 radius: width/2;
 84             }
 85             Rect//黃燈
 86             {
 87                 id:yellowLight;
 88                 color:"black";
 89                 radius: width/2;
 90             }
 91 
 92             transitions:
 93             [
 94                 Transition //提供從red狀態到yellow狀態的漸變過程
 95                 {
 96                     from: "red"
 97                     to: "yellow"
 98               //      ScriptAction { script: dosomething(); }  //能夠正常調用
 99                     ColorAnimation{ target: redLight; properties: "color";duration: 1000;}
100                     ColorAnimation{ target: yellowLight; properties: "color";duration: 1000;}
101                 }
102             ]
103         }
104         property bool m_bIsRed : false;
105         MouseArea
106         {
107             anchors.fill: parent;
108             onClicked://鼠標點擊時,狀態切換
109             {
110                 if (ligheGroup.state == "red"
111                         || ligheGroup.state == "green")
112                 {
113                     ligheGroup.state = "yellow";
114                 }
115                 else
116                 {
117                     if (parent.m_bIsRed == false)
118                     {
119                         ligheGroup.state = "red";
120                         parent.m_bIsRed = true;
121                     }
122                     else
123                     {
124                         ligheGroup.state = "green";
125                         parent.m_bIsRed = false;
126                     }
127                 }
128             }
129         }
130     }
131 }

四、紅綠燈,不一樣於上述紅綠燈,次紅綠燈只須要鼠標單擊觸發運行,狀態是由定時器來控制,紅燈運行60秒,綠燈20秒,黃燈3秒,爲了程序的迅速反應,在紅燈和綠燈的時候定時器觸發頻率全部提升,具體請看代碼,此處我只貼出定時器部分,若是須要整個運行程序,可自行下載demo。

 1 property bool m_bIsRed : false;//是不是紅燈亮
 2     property int m_iTicker : 0;
 3 
 4     Timer
 5     {
 6         id:redState;
 7         interval: 50;//每隔50毫秒觸發一次,真實狀況下本應該是1000毫秒一次
 8         repeat: true;
 9         triggeredOnStart: true;
10         property int count : 60;//紅燈秒數
11 
12         onTriggered: {
13             if (lightGroup.state != "red")
14             {
15                 lightGroup.state = "red";
16                 root.m_bIsRed = true;
17             }
18 
19             ++m_iTicker;
20             redLight.text = count - m_iTicker;
21             if (count <= m_iTicker)//到達指定時間 重置計數器,並切換到黃燈定時器,關閉自身定時器
22             {
23                 m_iTicker = 0;
24                 yellowState.start();
25                 redState.stop();
26             }
27         }
28     }
29     Timer
30     {
31         id:yellowState;
32         interval: 1000;
33         repeat: true;
34         triggeredOnStart: true;
35         property int count : 3;//黃燈秒數
36 
37         onTriggered: {
38             if (lightGroup.state != "yellow")
39             {
40                 lightGroup.state = "yellow";
41             }
42             ++m_iTicker;
43             yellowLight.text = count - m_iTicker;
44             if (count <= m_iTicker)//到達指定時間 重置計數器,並切換到綠燈/紅燈定時器,關閉自身定時器
45             {
46                 m_iTicker = 0;
47                 if (m_bIsRed)
48                 {
49                     greenState.start();
50                 }
51                 else
52                 {
53                     redState.start();
54                 }
55                 stop();
56             }
57         }
58     }
59     Timer
60     {
61         id: greenState;
62         interval: 150;//每隔150毫秒觸發一次,真實狀況下本應該是1000毫秒一次
63         repeat: true;
64         triggeredOnStart: true;
65         property int count : 20;//綠燈秒數
66 
67         onTriggered: {
68             if (lightGroup.state != "green")
69             {
70                 lightGroup.state = "green";
71                 root.m_bIsRed = false;
72             }
73 
74             ++m_iTicker;
75             greenLight.text = count - m_iTicker;
76             if (count <= m_iTicker)//到達指定時間 重置計數器,並切換到黃燈定時器,關閉自身定時器
77             {
78                 m_iTicker = 0;
79                 yellowState.start();
80                 greenState.stop();
81             }
82         }
83     }

五、日曆窗口,代碼量不大,有興趣的能夠看看,主要就是界面展現,若是想要作到動態的日曆,須要對模型動態的增刪,這個功能後續咱們在完善。

 1 import QtQuick 2.6
 2 import QtQuick.Window 2.0
 3 import QtGraphicalEffects 1.0
 4 
 5 import "../contrl"
 6 
 7 Window
 8 {
 9     visible: true;
10     width: 300;
11     height: 300;
12 
13     Rectangle
14     {
15         id:root;
16         anchors.fill: parent;
17         width: root.width;
18         height: root.height;
19         color: "yellow";
20 
21         //日期頭
22         Row
23         {
24             id: weekname;
25             spacing: 2;
26             padding: 5;
27 
28             Repeater
29             {
30                 model: ["周天", "週一", "週二", "週三", "週四", "週五", "週六"]
31                 Rectangle
32                 {
33                     width: (root.width - 6 * weekname.spacing - 10) / 7;
34                     height: 30
35                     radius: 3
36                     color: "lightBlue"
37                     Text
38                     {
39                         anchors.centerIn: parent
40                         text: modelData
41                     }
42                 }
43             }
44         }
45 
46         //
47         GridView
48         {
49             id: weekday;
50             boundsBehavior: Flickable.StopAtBounds;
51             anchors//佈局
52             {
53                 top: weekname.bottom;
54                 left:root.left;
55                 leftMargin:5;
56                 right: root.right;
57                 rightMargin:5;
58                 bottom: root.bottom;
59             }
60             model: 42;//天數
61 
62             cellWidth: (root.width - 10) / 7;
63             cellHeight: (root.width - 10) / 7;
64 //            Repeater
65 //            {
66 //                Rectangle
67 //                {
68 //                    radius: 8;
69 //                    color: "lightBlue";
70 //                    Text
71 //                    {
72 //                        anchors.centerIn: parent;
73 //                        text: modelData;
74 //                    }
75 //                }
76 //            }
77             delegate: numberDelegate;
78             focus: true;//能夠獲取焦點
79         }
80 
81         Component//繪製代理
82         {
83             id: numberDelegate;
84             Rectangle
85             {
86                 width: weekday.cellWidth;
87                 height: weekday.cellHeight;
88                 color: GridView.isCurrentItem ? "green" : "lightGreen"//根據是不是當前項設置顏色
89                 border.color: Qt.lighter("green");
90                 Text
91                 {
92                     anchors.centerIn: parent;
93                     font.pixelSize: 10;
94                     text: index + 1;//文本取索引值
95                 }
96             }
97         }
98     }
99 }
View Code

    補充:示例代碼中:GridView中的repeater元素是不須要的,repeater是配合定位器使用的模型,由於每個repeater都包含一個默認的繪製代理。

5、下載連接

    qml簡單示例

注:這是qml學習系列的第一篇文章,後邊我還會以這種示例的形式繼續更新更多學習的進度,但願你們多多支持,有問題的小夥伴能夠私信我。謝謝。。。

 

若是您以爲文章不錯,不妨給個 打賞,寫做不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

  1. 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。 

相關文章
相關標籤/搜索