QML 自定义控件Button,采用QtQuick.Controls 1.0和2.0两版本实现

        在开发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("单击");
        }
    }

}

        如上面代码所示,自定义控件可省去大多重复代码,并且可以只需要改变很少的属性就可以改变每个控件的独立属性,比较推荐使用。运行后的展示如下:

 欢迎各位大佬评论,私信指正。

import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 //import QtQuick 2.2 //import QtQuick.Controls 2.2 import QtQuick.Layouts 1.15 import QtQuick.Controls.Material 2.14 import QtQuick.Controls.Private 1.0 Page { anchors.fill: parent font.pixelSize: 12 header: Label { text: qsTr("系统设置") font.pixelSize: Qt.application.font.pixelSize * 2 padding: 10 } ColumnLayout { anchors.fill: parent spacing: 10 // 传感器序列号输入 Label { text: qsTr("传感器序列号") } TextField { id: sensorSerialNumber placeholderText: qsTr("输入传感器序列号") } // 测试日期输入 Label { text: qsTr("测试日期") } DatePicker{ dateValue: (new Date()).toLocaleString(Qt.locale(), "yyyy-MM-dd") onDateValueChanged: {} } // 传感器类型选择 Label { text: qsTr("传感器类型") } ComboBox { id: sensorType model: [qsTr("加速度"), qsTr("速度"), qsTr("位移")] currentIndex: 0 } // 传感器耦合方式选择 Label { text: qsTr("传感器耦合方式") } ComboBox { id: couplingType model: [qsTr("电压"), qsTr("IPEPE"), qsTr("电荷"), qsTr("4-20MA(DC)"), qsTr("4-20MA(AC)")] currentIndex: 0 } // 按钮区域 RowLayout { spacing: 10 Button { id: sensitivityTestButton text: qsTr("灵敏度测试") icon.source: "/api/placeholder/32/32" // 这里使用占位符图片,你需要替换为实际图片路径 } Button { id: frequencyResponseTestButton text: qsTr("频响测试") icon.source: "/api/placeholder/32/32" // 这里使用占位符图片,你需要替换为实际图片路径 } Button { id: dataManagementButton text: qsTr("数据管理") icon.source: "/api/placeholder/32/32" // 这
03-19
<think>好的,我现在需要帮助用户解决如何在Qt Quick Controls 2QML中创建包含传感器配置的页面,具体包括序列号输入、日期选择器、组合框按钮操作。首先,我需要回忆一下Qt Quick Controls 2中的常用组件以及QML布局相关的知识。 用户提到的组件有序列号输入,这应该是一个文本框,可能需要验证输入是否为有效的序列号格式。日期选择器可以使用QtQuick.Controls中的DatePicker或者类似的组件,但要注意Qt Quick Controls 2版本是否支持。组合框对应的是ComboBox组件,用来让用户选择预设的选项。按钮操作则涉及Button组件相应的点击事件处理。 接下来,布局设计。通常QML中使用ColumnLayout或GridLayout来排列组件,这样可以让界面自适应窗口大小。可能需要设置各组件之间的间距对齐方式。此外,传感器相关的UI可能需要实时更新数据,所以需要绑定数据模型或者使用属性绑定。 然后,我需要考虑如何将这些组件组合在一起。例如,每个配置项可能需要一个标签(Label)对应的输入控件,排列成一行或者一列。日期选择器可能需要弹出式对话框,或者使用内联的控件,这取决于用户需求。组合框需要填充选项,可能通过ListModel来动态添加。 按钮操作部分,用户点击后需要执行保存配置或者提交数据的功能。这里需要编写JavaScript函数来处理点击事件,可能需要将输入的数据收集起来,通过信号发送到C++后端处理,或者使用Qt的网络模块发送到服务器。 还需要注意样式美化,比如使用Qt Quick Controls 2的Material或Universal样式,或者自定义组件的外观。确保控件不同平台屏幕尺寸下表现一致。 可能遇到的问题包括日期选择器的实现,因为Qt Quick Controls 2中的标准组件可能没有现成的DatePicker,可能需要自定义或者使用Qt Labs中的Calendar组件。另外,组合框的数据填充可能需要动态加载,比如从文件或数据库中读取选项。 最后,测试布局的响应式设计,确保在窗口大小变化时,组件能够正确调整位置大小。同时,验证用户输入的合法性,比如序列号的格式是否正确,日期是否在合理范围内,组合框是否有选中项等。 总结步骤应该是:创建布局容器,添加各个输入控件并设置属性,处理按钮点击事件,绑定数据模型,进行样式调整,测试功能。需要参考Qt官方文档确保语法正确,并考虑代码的可维护性扩展性。</think>以下是如何使用Qt Quick Controls 2创建传感器配置页面的分步实现方案: ### 一、基础布局设计 使用`ColumnLayout`容器实现垂直布局,包含传感器序列号输入、日期选择、组合框配置操作按钮: ```qml import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 ColumnLayout { spacing: 15 anchors.fill: parent anchors.margins: 20 Label { text: "传感器配置" font.bold: true Layout.alignment: Qt.AlignHCenter } } ``` ### 二、核心组件实现 #### 1. 序列号输入 ```qml TextField { id: serialInput Layout.fillWidth: true placeholderText: "输入传感器序列号" validator: RegExpValidator { regExp: /[A-Z0-9]{8}-[A-Z0-9]{4}/ // 验证格式如XXXX-XXXX-XXXX } } ``` #### 2. 日期选择器 使用`Popup`实现日历选择: ```qml Button { text: "校准日期: " + Qt.formatDate(datePicker.selectedDate, "yyyy-MM-dd") onClicked: datePicker.open() DatePickerPopup { id: datePicker onDateSelected: console.log("选定日期:", selectedDate) } } // 日期选择弹窗组件 Popup { id: datePicker property date selectedDate: new Date() Calendar { onClicked: { selectedDate = date datePicker.close() } } } ``` #### 3. 组合框配置 ```qml ComboBox { Layout.fillWidth: true model: ["温度传感器", "压力传感器", "光学传感器"] currentIndex: 0 onActivated: console.log("选择类型:", currentText) } ``` ### 三、按钮操作逻辑 ```qml RowLayout { spacing: 10 Layout.topMargin: 20 Button { text: "保存配置" onClicked: { if(serialInput.acceptableInput){ backend.saveConfig( serialInput.text, datePicker.selectedDate, typeCombo.currentText ) // 假设有C++后端接口[^2] } } } Button { text: "重置" flat: true onClicked: serialInput.clear() } } ``` ### 四、样式优化建议 1. 在`ApplicationWindow`中设置全局样式: ```qml ApplicationWindow { Material.theme: Material.Dark Material.accent: "#2ecc71" } ``` 2. 添加输入验证提示: ```qml Label { visible: !serialInput.acceptableInput text: "序列号格式要求:8位字母数字+分隔符+4位字母数字" color: "red" } ``` ### 五、数据绑定示例 通过Qt的属性绑定实现实时更新: ```qml property string currentConfig: JSON.stringify({ "serial": serialInput.text, "date": datePicker.selectedDate, "type": typeCombo.currentText }) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值