Qml自定义组件的使用
2018-06-01 本文已影响0人
崔希羽
Component
是可重用的、封装的、具有定义良好的接口的QML类型。组件通常由组件文件定义,即.qml文件。组件类型本质上允许在QML文件中内联定义QML组件,而不是作为单独的QML文件。这对于在QML文件中重用小组件或定义逻辑上属于文件中其它QML组件的组件可能很有用。
1. 在单独文件中定义Component,文件名即是组件名称,且首字母必须为大写,例如创建BusyIndicator.qml文件,样式可以随意写,顶层Item可使用Rectangle,control,Button,Window等等...
import QtQuick 2.0
import QtQuick.Controls 2.2
Rectangle {
id: busyIndicatorComponents
property bool running: false
signal indicatorClicked
width: 20
height: 20
Button {
id: indicatorBtn
anchors.fill: parent
background: Image {
id: indicatorImage
source: indicatorBtn.pressed ? "../images/h.png" : "../images/n.png"
}
onClicked: {
indicatorClicked() //点击组件可发出信号
}
NumberAnimation on rotation {
id: rotaionAnimation
from: 0
to: 360
loops: Animation.Infinite
duration: 1000
}
}
//running值的变化控制是否转圈
onRunningChanged: {
if(running){
rotaionAnimation.start()
}else{
rotaionAnimation.stop()
}
}
}
使用示例:
BusyIndicator{
id: busyIndicator
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
onIndicatorClicked: {
//订阅信号 to do...
}
}
2.在文件内定义Component,也有人称之为嵌入式定义Component。这种方式需要使用Component类型来定义,它只能包含一个顶层的Item,除了这个Item之外不能定义任何数据(id除外),Item之内可以有多个子Item。常见的ListView的delegate,TableView的ItemDelegate就是典型的使用示例。有时候我们需要在当前的组件内重复创建多个相同样式的小组件,如两个相同样式的按钮:
Component {
id:verticalButtonComponent
Rectangle{
property string buttonName //按钮标题
property url defaultSource //普通状态图片url
property url hoverSource //鼠标放上去图片url
property url highlightSource //点击时图片url
id:verticalButtonContent
color: "transparent"
Image{
id:verticalButtonIcon
width: parent.width
height: parent.width
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
source: verticalButtonContent.defaultSource
}
Text {
id: verticalButtonText
anchors.top: verticalButtonIcon.bottom
anchors.topMargin: 6
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: 14
color: "white"
text:verticalButtonContent.buttonName
}
MouseArea {
id: vbtn_ma
anchors.fill: verticalButtonIcon
hoverEnabled: true //可响应悬停
onEntered: {
verticalButtonIcon.source = verticalButtonContent.hoverSource
}
onExited: {
verticalButtonIcon.source = verticalButtonContent.defaultSource
}
onPressed: {
verticalButtonIcon.source = verticalButtonContent.highlightSource
}
onReleased: {
//松开鼠标时如果鼠标还在控件的区域内 变成悬停时的图片
if(containsMouse){
verticalButtonIcon.source = verticalButtonContent.hoverSource
}
}
}
}
}
通过Loader来加载这个自定义组件,Loader继承自Item, 组件的位置以及大小在Loader中设置,sourceComponent
就是Component的id
. 当我们想要销毁时将sourceComponent设置为undefined
即可。使用示例:
Loader {
id: msgButtonLoader
sourceComponent: verticalButtonComponent
anchors.left: parent.left
anchors.leftMargin: 534
anchors.top: parent.top
anchors.topMargin: 16
width: 52
height: 74
//组件加载完成后进行配置
onLoaded: {
item.buttonName = "消息"
item.defaultSource = "../images/lobby_header_msg_default.png"
item.hoverSource = "../images/lobby_header_msg_hover.png"
item.highlightSource = "../images/lobby_header_msg_highlight.png"
}
}
PS
: 还有一个经常和Loader一起使用的Connections
,创建一个QML信号连接,指定target
目标,可以目标信号在这里订阅。示例:
Loader{ id:exitDialogLoader }
Connections{
target: exitDialogLoader.item
onMakesureButtonClicked: {
exitDialogLoader.sourceComponent = undefined
maskRect.visible = false
Qt.quit()
}
onCancelButtonClicked: {
exitDialogLoader.sourceComponent = undefined
maskRect.visible = false
}
}