參考文章:
1. 使用QML進行界面開發
一、Rectangle、ListView、Text、Component基本使用
效果如下:
最上面是一個ListView,里面填充100個Component,文本為其索引
中間是個圓角矩形,綁定一個點擊事件,點擊時改變顏色
下面是三個按鈕Component,點擊時觸發Component本身的的信號函數,在main.qml中通過connect關聯槽函數,改變中間的文本
main.qml 代碼:
import QtQuick 2.9 import QtQuick.Controls 2.2 // 常用界面構建類型:Rectangle、Image、Text、MouseArea、Item等 // 使用Rectangle就可以構建出消息展示框和按鈕等大部分的界面元素了 // 而Text類型可以用於在Rectangle中增加文字信息 // Image可以加載圖片,MouseArea提供鼠標/觸摸屏事件,組合使用這幾個元素就能夠快速的搭建基本的交互界面了 // 更復雜的類型:Row、Column、ListView、GridView等更復雜的元素 // 這類元素的設計理念是將數據與展現效果分開,數據用model來存放,而展示效果用view來描述 // model和view通過delegate聯系起來 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") // Rectangle:矩形對象 // QML中的元素是以層級的形式進行描述,子元素繼承父元素的坐標系統, // 子元素的坐標以父元素作為參考,父元素的左上角為子元素的坐標原點,子元素中可以以parent關鍵字引用父元素 Rectangle{ id: radius_rect y: 100 width: 100 height: 100 color: "red" radius: 10 // 圓角 MouseArea { anchors.fill: parent onClicked: { radius_rect.color = "blue" } } } // 一個簡單的ListView的用法示例如下: // Background類型構建一個背景區域 Rectangle { width: parent.width height: 80 color: "#EEEEEE" // 背景區域內有個ListView ListView { anchors.fill: parent anchors.margins: 20 spacing: 4 clip: true model: 100 orientation: ListView.Horizontal delegate: numberDelegate // delegate委托,指向一個Component對象 } } // Component時封裝好的可復用組件,通常用來給一個View提供圖形化組件 // ListVIew::delegate屬性就需要一個Component來指定如何顯示列表的每一個項 // ButtonStyle::background屬性也需要一個Component來指定如何繪制Button的背景 // https://www.cnblogs.com/adorkable/p/8277346.html Component { id: numberDelegate Rectangle { width: 40 height: 40 color: "green" Text { anchors.centerIn: parent // 文本在父元素矩形的居中顯示 text: index } } } Text { id: coloredText anchors.centerIn: parent anchors.top: parent.top anchors.topMargin: 4 text: "ColorPicker" font.pixelSize: 32 } // 槽函數 function setTextColor(clr) { coloredText.color = clr } // 自定義外部類型 ColorPicker { y: 100 id: redColor color: "red" focus: true width: parent.width / 3 - 4 anchors.left: parent.left anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 KeyNavigation.right: blueColor KeyNavigation.tab: blueColor // 在元素內部定義自己的信號處理函數,而不是綁定到統一的槽函數 onColorPicked: { coloredText.color = clr } } ColorPicker { id: blueColor color: "blue" width: parent.width / 3 - 4 anchors.left: redColor.right anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 KeyNavigation.left: redColor KeyNavigation.right: pinkColor KeyNavigation.tab: pinkColor } ColorPicker { id: pinkColor color: "pink" width: parent.width / 3 - 8 anchors.left: blueColor.right anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 KeyNavigation.left: blueColor KeyNavigation.tab: redColor } // 元素渲染完成事件 Component.onCompleted: { // 渲染完成時關聯信號和槽函數 blueColor.colorPicked.connect(setTextColor) pinkColor.colorPicked.connect(setTextColor) } }
ColorPicker是一個外部定義的Component,ColorPicker.qml代碼:
import QtQuick 2.9 // 自定義顏色選擇按鈕 Rectangle { id: colorPicker width: 50 height: 30 // 定義一個colorPicked信號函數,在使用時綁定到槽函數 signal colorPicked(color clr); function configureBorder() { colorPicker.border.width = colorPicker.focus ? 2 : 0; colorPicker.border.color = colorPicker.focus ? "#90D750" : "#808080"; } MouseArea { anchors.fill: parent // 鼠標點擊當前矩形的時候會發出colorPicked信號 onClicked: { colorPicker.colorPicked(colorPicker.color); mouse.accepted = true; colorPicker.focus = true; } } Keys.onReturnPressed: { // 對應Enter鍵 console.log("ColorPicker:onReturnPressed"); colorPicker.colorPicked(colorPicker.color); event.accepted = true; } Keys.onSpacePressed: { // 對應Space鍵 console.log("ColorPicker:onSpacePressed"); colorPicker.colorPicked(colorPicker.color); event.accepted = true; } // 焦點改變事件(失去焦點和獲得焦點都算焦點改變,所以這個函數觸發兩次) onFocusChanged: { // 默認元素在渲染的時候獲得焦點,所以最后一個渲染完成的元素會獲得焦點 console.log("ColorPicker:onFocusChanged"); configureBorder(); } // 渲染完成事件 Component.onCompleted: { // z只有最后一個渲染完成的元素會被設置邊框 console.log("ColorPicker:onCompleted, color is " + colorPicker.color); configureBorder(); } }
文件結構:
ColorPicker.qml和main.qml放在同級目錄下,所以無需import就可在main.qml中直接引用定義的組件