【零基礎學QT】【045】Qml基本用法

本篇博客通過一個詳細的UI例子來逐個點介紹Qt Quick的基本用法,儘量通過簡單例子來覆蓋全部主要知識點,閱讀時請對照代碼來逐個理解各個知識點

Qt Quick基本用法

  • Demo使用技巧:由於以下代碼集中了大量知識點,同時顯示會特別混亂,大家只要通過visible: false隱藏無關元素即可
  • 註釋:Qml和Javascript一樣,通過雙斜槓添加註釋
  • 給元素設置id:每個節點都可以設置一個id屬性,其它元素可能通過id關聯這個節點,參照node01
  • 向DOM樹中添加節點:參照node02
  • 導入類庫:Window,Text等元素都來自Qt Quick類庫,需要導入後才能使用,參照首行import語句
  • Qml基本類型:Qml提供了int,real,string,bool,list等類型,不需要導入任何類庫就能使用
  • Qt Quick內置類型:Qt Quick提供了date,point,rect,size,基本控件等類型,導入Qt Quick模塊即可使用
  • Javascript類型:Qml可以像Javascript一樣,直接通過var來聲明一個對象,它沒有具體類名,但可以通過變量名直接訪問,參照node03和node04,node03聲明瞭一個innerObject對象,node04可以直接引用這個對象的值
  • 執行Javascript代碼:在onCompleted,onClicked等方法內,可以執行Javascript代碼,參照node04
  • 屬性引用:一個元素,可以直接使用其它元素的屬性值,或拿來進行運算,這個功能非常強大,比如我們想要高爲寬的一半時,只需寫出【height: width * 0.5】即可
  • 通過錨佈局定位元素:錨佈局允許通過錨點,邊距,填充,居中等方式組合來定位元素位置,參照node05
  • 設置元素點擊區域:通過給元素添加MouseArea子節點,可以爲元素添加點擊事件,並且可以控制點擊區域範圍,參照node06
  • 設置字體:通過給Text元素添加font子節點,就可以設置Text的字體,當font的屬性很簡單隻有一個的時候,也可以簡寫成【font.bold: true】這種格式,參照node07
  • 設置邊框:邊框的使用和字體同理,參照node08
  • 圖片控件:通過Image元素可以顯示圖片,參照node09
  • 設置鼠標滑入滑出事件:給MouseArea設置onEntered,onExited事件方法即可,參照node10
  • 自定義組件:由於篇幅較長,稍後我們開一篇專門的博客來講解
  • 編碼規範:由於一個Qml文件中可能包含諸多內容,爲了方便閱讀,應當有一個書寫規範,一般按照id,自定義屬性,屬性賦值,事件聲明,狀態聲明,動畫聲明,自定義函數的順序來編寫
  • 定義動畫:Qt內置了AnchorAnimation,ColorAnimation,NumberAnimation,PathAnimation,PropertyAnimation,RotationAnimation等常用動畫,非常前面,如node11所示,是一個簡單的顏色漸變動畫
  • 定義複雜動畫:上面介紹的是一個非常簡單的動畫,控件一創建便執行,實際大多情景比這個要複雜,動畫改變的屬性可能不止一個,動畫往往需要指定在狀態變化時執行,這時單純的Animation已經不再能滿足我們的需求,我們需要配合State和Transition來實現這些複雜動畫,參照node12
  • 數組簡寫:在Qml中數組通過[ ]來表示,但是當數組只有一個元素時,也可以省略[ ]
  • 加載Javascript代碼:Qml可以直接將Javascript加載爲一個模塊對象,直接進行使用,在這一點上,Qt Quick做得比原生Javascript更加先進,參照node13和import語句
  • 可視基類:所有的Qt Quick可視化元素,即控件節點,都繼承自Item,參照node14,像x,y,z,width,height這些基本屬性,都是繼承自Item的
  • 控件堆疊順序:當一個元素中包含多個子元素時,可以通過z值來控制元素的顯示順序,z值較大的將顯示在上面,遮擋z值較小的元素,默認的z值爲0,z值相同的情況下,排在佈局靠後的元素顯示在上層,參照node14
  • 座標轉換:同一個點相對於不同控件的座標是不同的,比如對於一個Window-Item-Rectangle的三級Dom結構,點相對於Window,Item,Rectangle的座標都是不一樣的,除非這三級節點的左上角都是對齊的,要獲取一個點相對於某個元素的座標位置,可以參考node15
  • 界面佈局:內容不難,但由於佈局有很多種,還有新版舊版之分,篇幅較長,接着我們開一篇專門博客來講解
  • 顯示富文本:Text可以顯示覆雜帶樣式的文本,如加粗,傾斜,彩色,鏈接,序號等,通過【textFormat: Text.StyledText】或【textFormat: Text.RichText】即可啓用對應的功能,StyledText僅支持基本的簡單文本標籤,RichText支持HTML4標籤
  • 使用文本編輯框:TextInput是一個文本編輯控件,但是它沒有任何默認樣式,甚至連基本的邊框都沒有,需要用戶自己定義,參照node16
  • 更多高級控件和屬性:Qt每個控件都包含了諸多屬性,每一個都可以寫成一幅長篇博客,但是不管對於新手還是老手來說,這都不是一個明智之舉,這裏只講解核心知識點和思路,以便大家可以快速上手進行Qt項目開發,具體細節可以用到時再探究,死背屬性意義不大,以後換一種語言,換一種框架,可能又是新的屬性和用法,沒太大複用價值

Demo源碼


	//main.qml
	
	import QtQuick 2.12
	import QtQuick.Window 2.12
	import "script/math.js" as MathScript
	
	//窗口節點
	Window {
	    id: node01
	    visible: true
	    width: 640
	    height: 480
	    title: "Qt Quick Demo"
	
	    //測試基本使用
	    Text {
	        id: node02
	        visible: false
	        text: "Node 02"
	    }
	
	    //測試Javascript對象
	    Text {
	        property var innerObject: ({
	                                       "title": "Node 04"
	                                   })
	
	        id: node03
	        visible: false
	        text: "Node 03"
	    }
	
	    //測試Javascript代碼
	    Text {
	        id: node04
	        visible: false
	        text: node03.innerObject.title
	
	        Component.onCompleted: {
	            var jsObject = {
	                "id": 1,
	                "name": "Javascript Object"
	            }
	
	            console.log(node03.text)
	            console.log(node04.text)
	            console.log(jsObject.name)
	        }
	    }
	
	    //使用矩形區域測試錨佈局
	    Rectangle {
	        id: node05
	        visible: false
	        width: 400
	        height: 400
	        radius: 5
	        color: "red"
	
	        anchors.left: parent.left
	        anchors.top: parent.top
	        anchors.leftMargin: 10
	        anchors.topMargin: 10
	    }
	
	    //測試點擊區域
	    Rectangle {
	        id: node06
	        visible: false
	        width: 400
	        height: 400
	        color: "red"
	        anchors.centerIn: parent
	
	        //只能點擊下半區域
	        MouseArea {
	            anchors.fill: parent
	            anchors.topMargin: parent.height * 0.5
	            onClicked: {
	                console.debug("Rectangle Clicked")
	            }
	        }
	    }
	
	    //測試字體
	    Text {
	        id: node07
	        visible: false
	        text: "Node 07"
	
	        font {
	            pointSize: 30
	            bold: true
	            italic: true
	        }
	    }
	
	    //測試邊框
	    Rectangle {
	        id: node08
	        visible: false
	        width: 200
	        height: 200
	        color: "yellow"
	
	        border {
	            color: "red"
	            width: 2
	        }
	    }
	
	    //測試圖片
	    Image {
	        id: node09
	        visible: false
	        source: "images/1.png"
	        width: parent.width
	        height: parent.height
	        fillMode: Image.Stretch
	    }
	
	    //測試鼠標懸浮事件
	    Rectangle {
	        id: node10
	        visible: false
	        width: 200
	        height: width
	        color: "yellow"
	        radius: 100
	        border.color: "red"
	        border.width: 2
	
	        MouseArea {
	            anchors.fill: parent
	            hoverEnabled: true
	            onEntered: {
	                parent.border.width = 4
	            }
	            onExited: {
	                parent.border.width = 2
	            }
	        }
	    }
	
	    //測試基本動畫
	    Rectangle {
	        id: node11
	        visible: false
	        width: 200
	        height: width
	        radius: 100
	
	        //控件創建時,執行一個顏色漸變動畫
	        ColorAnimation on color {
	            from: "yellow"
	            to: "orange"
	            duration: 3000
	        }
	    }
	
	    //測試複雜動畫
	    Rectangle {
	        id: node12
	        visible: false
	        width: 200
	        height: width
	        radius: 100
	        state: "A"
	
	        //點擊時切換到狀態B
	        MouseArea {
	            anchors.fill: parent
	            onClicked: {
	                node12.state = "B"
	            }
	        }
	
	        //聲明兩種狀態,指定狀態值
	        states: [
	            State {
	                name: "A"
	                PropertyChanges {
	                    target: node12
	                    color: "yellow"
	                }
	                PropertyChanges {
	                    target: node12.border
	                    width: 2
	                    color: "green"
	                }
	            },
	            State {
	                name: "B"
	                PropertyChanges {
	                    target: node12
	                    color: "orange"
	                }
	                PropertyChanges {
	                    target: node12.border
	                    width: 5
	                    color: "blue"
	                }
	            }
	        ]
	
	        //定義從A狀態切換到B狀態時的動畫
	        transitions: Transition {
	            from: "A"
	            to: "B"
	            ColorAnimation {
	                target: node12
	                duration: 3000
	            }
	            NumberAnimation {
	                target: node12.border
	                property: "width"
	                duration: 3000
	            }
	        }
	    }
	
	    //測試加載Javascript文件
	    Rectangle {
	        id: node13
	        visible: false
	        width: 200
	        height: width
	        radius: 100
	        color: "yellow"
	
	        Component.onCompleted: {
	            console.debug("MathScript", MathScript.sum(1, 1))
	        }
	    }
	
	    //測試Item
	    Item {
	        id: node14
	        visible: false
	        anchors.fill: parent
	
	        Rectangle {
	            width: 100
	            height: 100
	            x: 100
	            y: 100
	            z: 1
	            color: "red"
	        }
	
	        Rectangle {
	            width: 100
	            height: 100
	            x: 150
	            y: 150
	            z: -1
	            color: "lightblue"
	        }
	    }
	
	    //獲取控件座標
	    Rectangle {
	        id: node15
	        visible: false
	        anchors.fill: parent
	        color: "yellow"
	
	        Rectangle {
	            id: node15Rect
	            width: 100
	            height: 100
	            color: "red"
	            anchors.top: parent.top
	            anchors.left: parent.left
	            anchors.topMargin: 10
	            anchors.leftMargin: 10
	
	            Component.onCompleted: {
	                //將node15Rect中的點,轉化爲在node15中的座標
	                console.debug(node15.mapFromItem(node15Rect, 0, 0))
	                //將node15中的點,轉化爲在node15Rect中的座標
	                console.debug(node15.mapToItem(node15Rect, 10, 10))
	                //同理,可將Item中的座標與Window中的座標進行轉換
	                //由於Window不繼承自Item,需要通過Window.contentItem來獲得根節點
	                console.debug(node01.contentItem.mapFromItem(node15Rect, 0, 0))
	                console.debug(node01.contentItem.mapToItem(node15Rect, 10, 10))
	            }
	        }
	    }
	
	    //測試文本編輯框
	    Rectangle {
	        id: node16
	        visible: true
	        anchors.fill: parent
	        anchors.margins: 100
	        color: "yellow"
	
	        TextInput {
	            id: node16Input
	            anchors.fill: parent
	            text: "Hello World"
	            color: "red"
	            font.pointSize: 50
	            focus: true
	            clip: true //文本裁剪,可以防止文本超出parent顯示
	        }
	    }
	    
	}


	//math.js

	function sum (a, b) {
	    return a + b;
	}

發佈了429 篇原創文章 · 獲贊 43 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章