import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Shapes Item { id: control // 保持与框架一致的接口 property var value: false property int decimals: 0 property string text: "Enabled" property color textColor: "black" property color checkedColor: "#2196F3" property color uncheckedColor: "#cccccc" property color checkedBoxColor: "white" property color uncheckedBoxColor: "white" property int boxSize: 16 property int spacing: 8 property int textSize: 12 property alias font: label.font // 与框架一致的信号 signal asValueChanged(value: var) signal boolValueChanged(bool checked) // 辅助信号,避免与内置信号冲突 implicitHeight: Math.max(boxSize, label.implicitHeight) implicitWidth: boxSize + spacing + label.implicitWidth function toggle() { var newValue = !getBoolValue() setValue(newValue) } function setValue(newValue) { var boolValue = getBoolValue() var newBoolValue = toBool(newValue) if (boolValue !== newBoolValue) { value = newBoolValue boolValueChanged(newBoolValue) asValueChanged(newBoolValue) } } function getBoolValue() { return toBool(value) } function toBool(value) { if (typeof value === 'boolean') { return value } else if (typeof value === 'number') { return value !== 0 } else if (typeof value === 'string') { var str = value.toString().toLowerCase() return str === 'true' || str === '1' || str === 'on' } return false } // 整个区域的点击事件 MouseArea { anchors.fill: parent onClicked: function(mouse) { control.toggle() mouse.accepted = true } } RowLayout { anchors.fill: parent spacing: control.spacing // 复选框 Rectangle { id: checkBox width: control.boxSize height: control.boxSize radius: 3 border.color: getBoolValue() ? control.checkedColor : control.uncheckedColor border.width: 1 color: getBoolValue() ? control.checkedColor : control.uncheckedBoxColor Layout.alignment: Qt.AlignVCenter // 勾选标记 Shape { anchors.centerIn: parent width: 10 height: 8 visible: getBoolValue() ShapePath { strokeColor: "transparent" fillColor: control.checkedBoxColor strokeWidth: 0 PathMove { x: 0; y: 4 } PathLine { x: 4; y: 8 } PathLine { x: 10; y: 0 } PathLine { x: 9; y: 0 } PathLine { x: 4; y: 7 } PathLine { x: 1; y: 4 } } } // 悬停效果 Rectangle { anchors.fill: parent radius: parent.radius color: "transparent" border.color: "#888888" border.width: boxMouseArea.containsMouse ? 1 : 0 opacity: boxMouseArea.containsMouse ? 0.3 : 0 } // 复选框自身的点击事件 MouseArea { id: boxMouseArea anchors.fill: parent hoverEnabled: true onClicked: function(mouse) { control.toggle() mouse.accepted = true } } } // 标签文本 Label { id: label text: control.text color: control.textColor font.pixelSize: control.textSize verticalAlignment: Text.AlignVCenter Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true // 鼠标悬停在文本上时的点击事件 MouseArea { anchors.fill: parent onClicked: function(mouse) { control.toggle() mouse.accepted = true } } } } // 键盘支持 Keys.onPressed: function(event) { if (event.key === Qt.Key_Space || event.key === Qt.Key_Return) { control.toggle() event.accepted = true } } // 聚焦支持 activeFocusOnTab: true // 聚焦时的边框 Rectangle { anchors.fill: parent color: "transparent" border.color: control.activeFocus ? "#2196F3" : "transparent" border.width: 2 radius: 2 visible: control.activeFocus } // 当value从外部改变时,更新显示 onValueChanged: { var boolValue = getBoolValue() if (checkBox.border.color !== (boolValue ? control.checkedColor : control.uncheckedColor)) { checkBox.border.color = boolValue ? control.checkedColor : control.uncheckedColor checkBox.color = boolValue ? control.checkedColor : control.uncheckedBoxColor } } }