在开发QtQuick项目时,对于界面上的控件Controls往往会重复使用,单个界面上会有多个同样的Controls。在调用系统Controls库时,往往一些属性,如字体、样式、大小等需要多次去编写,造成代码重复冗余,而且一些项目要求的特殊属性系统Controls也无法全部满足,因此,在QtQuick项目中,自定义自己项目的控件对于项目的开发具有很大好处。
QT对于QtQuick.Controls库提供的1.0和2.0版本,两个版本的相同控件并不支持混用,同时QtQuick.Controls的Button控件无法直接指定字体大小等属性,无法满足指定属性项目的需求,因此需要自定义此Controls。因此本文对于1.0和2.0版本的Button给出了两个自定义的控件版本,具体自定义实现见下文。
1.0版本自定义Button
1.0版本即qml文件头引入QtQuick.Controls 1.0 - 1.4库的适用版本,具体见自定义控件代码:
/*
* 自定义QML Button控件
* Since:Qt 5.1 采用QtQuick.Controls 1.4库(1.0版)
* 此方式同样也可采用2.0版本方式定义
*/
import QtQuick 2.12
import QtQuick.Controls 1.4
Rectangle {
id: control;
// 定义Button字体属性
property alias text: buttonText.text; // 按钮名称
property alias fontSize: buttonText.font.pixelSize; // 名称字体大小
property alias fontFamily: buttonText.font.family; // 名称字体样式
// 定义Button可响应信号
signal clicked; // 单击
signal doubleClicked; // 双击
signal pressed; // 压
signal released;
signal entered;
signal exited;
// 定义Button形状
implicitWidth: 60; // 最小宽度
implicitHeight: 30; // 最小高度
color: control.enabled ? (mouse.pressed ? "#0b81ff" : "transparent") : "#E5E5E5"; // 自定义Button颜色
border.width: 1; // 边框宽度
border.color: mouse.hovered ? "#0b81ff" : "#E5E5E5"; // 边框颜色
radius: 5; // 弧度
// 定义按钮名称
Text {
id: buttonText;
anchors.centerIn: parent;
text: control.text;
font.pixelSize: 12; // 默认字体大小
font.family: "Microsoft YaHei"; // 字体样式
color: "#333333"; // 字体颜色
renderType: Text.NativeRendering; // 防止字体模糊
}
// 定义按钮鼠标点击事件
MouseArea {
id: mouse;
anchors.fill: parent;
hoverEnabled: true; // 悬停事件使能
onEntered: {
control.entered();
}
onExited: {
control.exited();
}
onClicked: {
control.clicked();
}
onDoubleClicked: {
control.doubleClicked();
}
onPressed: {
control.pressed();
}
onReleased: {
control.released();
}
}
}
此版本的Button,由外框矩形和内部Text组成,按钮的事件信号由鼠标事件定义完成。
1.0版本自定义Button有如下的缺点:
1. button的背景大小无法自适应按钮文文字大小,需求根据当前的按钮名称指定按钮宽度。
2. 无法监测鼠标悬停事件。
3. 控件本身鼠标焦点在选中后难以转移,会出现点击其他控件出现两次才会响应,可采用forceActiveFocus()函数来转移焦点。
2.0版本自定义Button
2.0版本即qml文件头引入QtQuick.Controls 2.0 - 2.12库的适用版本,具体见自定义控件代码:
/*
* 自定义QML Button控件
* Since:Qt 5.7 采用QtQuick.Controls 2.12库(2.0版)
*/
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12
import QtQuick.Templates 2.12 as T
T.Button {
id: control;
property alias fontSize: control.font.pixelSize; // 名称字体大小
property alias fontFamily: control.font.family; // 名称字体样式
// 按钮属性
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding); // 最小高度
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding); // 最小宽度
hoverEnabled: true;
padding: 6;
spacing: 6;
horizontalPadding: padding + 2; //2.0版本属性
font.family: "Microsoft YaHei";
font.pixelSize: 12;
// 按钮名称属性
contentItem: Label {
height: back.height;
width: back.width;
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignHCenter; // 字体位置 水平和垂直的中心
text: control.text;
font: control.font;
color: "#333333";
renderType: Text.NativeRendering;
}
// 按钮背景属性
background: Rectangle {
id: back;
implicitWidth: 60;
implicitHeight: 30;
visible: !control.flat || control.down || control.checked || control.highlighted;
color: control.enabled ? (control.pressed ? "#0b81ff" : "transparent") : "#E5E5E5";
border.width: 1;
border.color: control.hovered ? "#0b81ff" : "#E5E5E5";
radius: 5;
}
}
自定义2.0版本的Button的属性于目前使用来说,体验比较良好,如果项目不要求版本,建议使用此版本的自定义Button。
自定义Button应用
在main.qml中使用自定义的Controls Button时,需先引入定义此控件的路径,并且最好将包含自定义控件的的路径as成专用的首字母大写的关键字,如下代码:
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.12
import "myControl" as My
Window {
visible: true;
width: 640;
height: 480;
title: qsTr("自定义Control");
My.Botton1 {
id: button1;
anchors.top: parent.top;
anchors.topMargin: 30;
anchors.left: parent.left;
anchors.leftMargin: 50;
width: 110; // 指定适应text宽度的 按钮宽度
text: qsTr("Control 1.4版本");
onClicked: {
console.log("单击");
}
}
My.Button2 {
id: button2;
anchors.top: button1.bottom;
anchors.topMargin: 30;
anchors.left: parent.left;
anchors.leftMargin: 50;
text: qsTr("Control 2.12版本");
onClicked: {
console.log("单击");
}
}
Button {
id: button;
anchors.top: button2.bottom;
anchors.topMargin: 30;
anchors.left: parent.left;
anchors.leftMargin: 50;
text: qsTr("Qt库 版本");
/*
// 字体
// 名称
contentItem: Label {
}
// 背景
background: Rectangle {
}
*/
onClicked: {
console.log("单击");
}
}
}
如上面代码所示,自定义控件可省去大多重复代码,并且可以只需要改变很少的属性就可以改变每个控件的独立属性,比较推荐使用。运行后的展示如下:
欢迎各位大佬评论,私信指正。