参考文章:
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 640 height: 480 title: qsTr("Hello World") // Rectangle:矩形对象 // QML中的元素是以层级的形式进行描述,子元素继承父元素的坐标系统, // 子元素的坐标以父元素作为参考,父元素的左上角为子元素的坐标原点,子元素中可以以parent关键字引用父元素 Rectangle{ id: radius_rect y: 100 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 { 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 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" 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" 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 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中直接引用定义的组件