我们在日常开发中都会封装一些组件以便于项目内重复利用。QML创建可重用组件一般有两种方法。
- 自定义Item
- 使用Component创建自定义组件
自定义Item
以一个自定义按钮举例:
import QtQuick 2.12Rectangle {id: root// 自定义属性property string btnDis: qsTr("button")property string pressedColor: "yellow"property string normalColor: "gray"property int btnw: 80property int btnh: 20signal btnClickedradius: 4width: disStr.width> root.width? disStr.width + 8 : btnwheight: btnhcolor: mouseArea.pressed? pressedColor : normalColorText {id: disStranchors.centerIn: parenttext: btnDis}MouseArea {id: mouseAreaanchors.fill: parentonClicked: root.btnClicked()}
}
然后再主文件直接使用元素即可:
import QtQuick 2.12
import QtQuick.Window 2.12Window {id:rootvisible: truewidth: 640height: 480title: qsTr("简单窗口")RadiusButton {id: loginBtnanchors.centerIn: parentbtnDis: qsTr("马大爷")btnh: 25pressedColor: "green"onBtnClicked: {console.log(qsTr("按钮点击了"))} }
}
注意:
如果出现找不到组件,则检查下是否将组件添加到了qrc中,如下图:
如果并不是在根目录下则需要import相应的文件夹,如下:
在main.qml中 import "qrc:/ui"即可。
通常,自定义组件时我们会以一个Item作为根节点,可以防止用户通过基本属性改变我们设计的按钮的属性色。修改之后为:
import QtQuick 2.12
Item {id: root// 自定义属性property string btnDis: qsTr("button")property string pressedColor: "yellow"property string normalColor: "gray"property int btnw: 80property int btnh: 20signal btnClickedwidth: rect.widthheight: rect.heightRectangle {id: rectanchors.fill: parentradius: 4width: disStr.width> rect.width? disStr.width + 8 : btnwheight: btnhcolor: mouseArea.pressed? pressedColor : normalColorText {id: disStranchors.centerIn: parenttext: btnDis}MouseArea {id: mouseAreaanchors.fill: parentonClicked: root.btnClicked()}}
}
其中,disStr.width> rect.width? disStr.width + 8 : btnw 即自适应按钮文字大小。
例如还有一个简单的登录界面:
LoginFrame.qml
import QtQuick 2.3
import QtQuick.Layouts
import QtQuick.Controls
import "qrc:/ui"Item {property int mwidth: 480property int mheight: 320property string placeholderAct: qsTr("请输入账号")property string placeholderPwd: qsTr("请输入密码")property string strAct: qsTr("账号:")property string strPwd: qsTr("密码:")property string bkcolor: "#dce7dc"property string logopath: ""property string bkimgpath: ""id: rootwidth: mwidthheight: mheightRectangle {id: loginframeanchors.fill:parentwidth: mwidthheight: mheightcolor: bkcolorborder.color: Qt.lighter(color)radius: 8Image {id: bkimageanchors.fill: parentwidth: 100height: 100source: bkimgpathfillMode: Image.PreserveAspectFit}RadiusImage {id: logoanchors.centerIn: parentanchors.verticalCenterOffset: -loginframe.height/2 + logo.imgwidth/2 + 15imgwidth: loginframe.height/4imgheight:loginframe.height/4 imgpath: logopath}Column{spacing:20anchors.centerIn:parentanchors.verticalCenterOffset: 20Row{id:row1spacing: 10Text{id:labelActtext: strActanchors.verticalCenter: account.verticalCenter}TextField{id: accountwidth: loginframe.width/2 - labelAct.widthplaceholderText: placeholderActbackground: Rectangle {width: parent.widthradius: 3}}}Row{id:row2spacing: 10Text{id:labelPwdwidth:labelAct.widthtext: strPwdanchors.verticalCenter:password.verticalCenter}TextField{id: passwordwidth: loginframe.width/2 - labelPwd.widthplaceholderText: placeholderPwdbackground: Rectangle {width: parent.widthradius: 3}}}}}
}
RadiusImage.qml
import QtQuick 2.0
import Qt5Compat.GraphicalEffectsItem {property string imgpath: ""property int imgwidth: 100property int imgheight: 100width: imgwidthheight: imgheightImage {id: imagesource: imgpathasynchronous: trueanchors.fill: parentwidth: imgwidthheight: imgwidthfillMode: Image.Stretchclip: truevisible: false}Rectangle {id: maskRecanchors.centerIn: parentwidth: image.widthheight: image.heightcolor:"transparent"Rectangle {anchors.centerIn: parentwidth: image.paintedWidthheight: image.paintedHeightcolor: "#edf6f9"border.color: "#e5f634"radius: 50}visible: true // 圆角边框及背景}OpacityMask {id: maskanchors.fill: imagesource: imagemaskSource: maskRec}
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import Qt.labs.platform 1.1
import "qrc:/ui"Window {visible: truewidth: ll.widthheight: ll.heightflags: Qt.FramelessWindowHintcolor: "transparent"LoginFrame {id: lllogopath:"qrc:/images/images/wheel.png"bkimgpath:"qrc:/images/images/background.png"}
}
界面效果: