《QT实用小工具·三十九》仿 Windows10 画图3D 的颜色选择器, 但更加强大

news/2025/1/12 21:36:39/

1、概述
源码放在文章末尾

该项目实现了仿 Windows10 画图3D 的颜色选择器,功能更加丰富更加强大。
在这里插入图片描述

项目部分代码如下所示:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15Item {id: rootwidth: 460height: 500scale: 0opacity: 0enabled: falseproperty bool movable: trueproperty alias title: contentText.textproperty color initColor: "white"readonly property color currentColor: pickerRect.currentColoronInitColorChanged: pickerRect.setColor(initColor);signal accepted();signal rejected();function open() {focus = true;enabled = true;}function hide() {focus = false;enabled = false;}Keys.onEscapePressed: cancelButton.clicked();NumberAnimation on scale {running: root.enabledduration: 350easing.type: Easing.OutBackeasing.overshoot: 1.0to: 1.0}NumberAnimation on opacity {running: root.enabledduration: 300easing.type: Easing.OutQuadto: 1.0}NumberAnimation on scale {running: !root.enabledduration: 300easing.type: Easing.InBackeasing.overshoot: 1.0to: 0.0}NumberAnimation on opacity {running: !root.enabledduration: 250easing.type: Easing.OutQuadto: 0.0}RectangularGlow {width: parent.width + 4height: parent.height + 4anchors.centerIn: parentglowRadius: 4spread: 0.2color: "#206856E6"cornerRadius: 4}Rectangle {anchors.fill: parentcolor: "#f6f6f6"border.color: "#aea4ee"}MouseArea {anchors.fill: parentenabled: root.movableproperty point startPos: Qt.point(0, 0)property point offsetPos: Qt.point(0, 0)onClicked: (mouse) => mouse.accepted = false;onPressed: (mouse) => {startPos = Qt.point(mouse.x, mouse.y);cursorShape = Qt.SizeAllCursor;}onReleased: (mouse) => {startPos = Qt.point(mouse.x, mouse.y);cursorShape = Qt.ArrowCursor;}onPositionChanged: (mouse) => {if (pressed) {offsetPos = Qt.point(mouse.x - startPos.x, mouse.y - startPos.y);root.x = root.x + offsetPos.x;root.y = root.y + offsetPos.y;}}Text {id: contentTextheight: 20anchors.top: parent.topanchors.topMargin: 15anchors.left: parent.leftanchors.leftMargin: 25anchors.right: parent.rightfont.family: "微软雅黑"color: "#222255"text: qsTr("选择新颜色")antialiasing: trueverticalAlignment: Text.AlignVCenter}Item {id: pickerRectwidth: 330height: 290anchors.top: contentText.bottomanchors.left: contentText.leftanchors.leftMargin: -cursorWidth * 0.5property real cursorWidth: 30property color hueColor: {let v = 1.0 - hueSlider.value;if (0.0 <= v && v < 0.16) {return Qt.rgba(1.0, 0.0, v / 0.16, 1.0);} else if (0.16 <= v && v < 0.33) {return Qt.rgba(1.0 - (v - 0.16) / 0.17, 0.0, 1.0, 1.0);} else if (0.33 <= v && v < 0.5) {return Qt.rgba(0.0, ((v - 0.33) / 0.17), 1.0, 1.0);} else if (0.5 <= v && v < 0.76) {return Qt.rgba(0.0, 1.0, 1.0 - (v - 0.5) / 0.26, 1.0);} else if (0.76 <= v && v < 0.85) {return Qt.rgba((v - 0.76) / 0.09, 1.0, 0.0, 1.0);} else if (0.85 <= v && v <= 1.0) {return Qt.rgba(1.0, 1.0 - (v - 0.85) / 0.15, 0.0, 1.0);} else {return "red";}}property real saturation: colorPickerCursor.x / (width - cursorWidth)property real brightness: 1 - colorPickerCursor.y / (height - cursorWidth)property color currentColor: Qt.hsva(hueSlider.value, saturation, brightness, alphaSlider.value)property color __color: Qt.rgba(0, 0, 0, 0)function setColor(color) {alphaSlider.x = alphaPicker.width == 0 ? 0 : (alphaPicker.width - alphaSlider.width) * color.a;hueSlider.x = (huePicker.width - hueSlider.width) * (Math.max(color.hsvHue, 0));colorPickerCursor.x = color.hsvSaturation * (width - cursorWidth);colorPickerCursor.y = (1.0 - color.hsvValue) * (height - cursorWidth);}function fromColor() {pickerRect.setColor(Qt.rgba(parseInt(redEditor.text) / 255., parseInt(greenEditor.text) / 255., parseInt(blueEditor.text) / 255., parseInt(alphaEditor.text) / 255.));}function fromArgbColor() {__color = '#' + argbEditor.text;pickerRect.setColor(__color);}onCurrentColorChanged: {redEditor.text = (currentColor.r * 255).toFixed(0);greenEditor.text = (currentColor.g * 255).toFixed(0);blueEditor.text = (currentColor.b * 255).toFixed(0);alphaEditor.text = (currentColor.a * 255).toFixed(0);argbEditor.text = currentColor.toString().replace("#", "");}Rectangle {x: pickerRect.cursorWidth * 0.5y: pickerRect.height - pickerRect.cursorWidth * 0.5width: pickerRect.height - pickerRect.cursorWidthheight: pickerRect.width - pickerRect.cursorWidthrotation: -90transformOrigin: Item.TopLeftgradient: Gradient {GradientStop { position: 0.0; color: "white" }GradientStop { position: 1.0; color: pickerRect.hueColor }}}Rectangle {x: pickerRect.cursorWidth * 0.5y: pickerRect.cursorWidth * 0.5width: pickerRect.width - pickerRect.cursorWidthheight: pickerRect.height - pickerRect.cursorWidthgradient: Gradient {GradientStop { position: 1.0; color: "#ff000000" }GradientStop { position: 0.0; color: "#00000000" }}}Rectangle {id: colorPickerCursorwidth: pickerRect.cursorWidthheight: pickerRect.cursorWidthborder.color: "#e6e6e6"border.width: 1color: pickerRect.currentColorBehavior on scale { NumberAnimation { easing.type: Easing.OutBack; duration: 300 } }Rectangle {anchors.fill: parentanchors.margins: 1color: "transparent"border.color: "white"border.width: 1}}MouseArea {x: pickerRect.cursorWidthy: pickerRect.cursorWidthanchors.fill: parentfunction handleCursorPos(x, y) {let halfWidth = pickerRect.cursorWidth * 0.5;colorPickerCursor.x = Math.max(0, Math.min(width , x + halfWidth) - pickerRect.cursorWidth);colorPickerCursor.y = Math.max(0, Math.min(height, y + halfWidth) - pickerRect.cursorWidth);}onPositionChanged: (mouse) => handleCursorPos(mouse.x, mouse.y);onPressed: (mouse) => {colorPickerCursor.scale = 0.7;handleCursorPos(mouse.x, mouse.y);}onReleased: colorPickerCursor.scale = 1.0;}}Item {id: previewItemwidth: 90height: 90anchors.left: pickerRect.rightanchors.leftMargin: 10anchors.top: contentText.bottomanchors.topMargin: 15Grid {id: previwBackgroundanchors.fill: parentrows: 11columns: 11clip: trueproperty real cellWidth: width / columnsproperty real cellHeight: height / rowsRepeater {model: parent.columns * parent.rowsRectangle {width: previwBackground.cellWidthheight: widthcolor: (index % 2 == 0) ? "gray" : "transparent"}}}Rectangle {anchors.fill: parentanchors.margins: -2color: pickerRect.currentColorborder.color: "#e6e6e6"border.width: 2}}component ColorEditor: ColumnLayout {id: __layoutwidth: previewItem.widthheight: 50property alias label: label.textproperty alias text: input.textproperty alias validator: input.validatorsignal textEdited();signal accepted();Text {id: labelfont.family: "微软雅黑"color: "#222255"verticalAlignment: Text.AlignVCenterLayout.fillWidth: true}Rectangle {clip: truecolor: "transparent"border.color: "#e6e6e6"border.width: 2Layout.fillHeight: trueLayout.fillWidth: trueTextInput {id: inputleftPadding: 10rightPadding: 10selectionColor: "#398ed4"selectByMouse: trueanchors.fill: parenthorizontalAlignment: TextInput.AlignRightverticalAlignment: TextInput.AlignVCenteronTextEdited: __layout.textEdited();onAccepted: __layout.accepted();}}}Column {anchors.top: previewItem.bottomanchors.topMargin: 10anchors.left: previewItem.leftspacing: 6ColorEditor {id: redEditorlabel: "红色"validator: IntValidator { top: 255; bottom: 0 }onAccepted: pickerRect.fromColor();}ColorEditor {id: greenEditorlabel: "绿色"validator: IntValidator { top: 255; bottom: 0 }onAccepted: pickerRect.fromColor();}ColorEditor {id: blueEditorlabel: "蓝色"validator: IntValidator { top: 255; bottom: 0 }onAccepted: pickerRect.fromColor();}ColorEditor {id: alphaEditorlabel: "透明度"validator: IntValidator { top: 255; bottom: 0 }onAccepted: pickerRect.fromColor();}ColorEditor {id: argbEditorlabel: "十六进制 (ARGB)"validator: RegularExpressionValidator { regularExpression: /[0-9a-fA-F]{0,8}/ }onAccepted: pickerRect.fromArgbColor();}}Rectangle {id: huePickerwidth: pickerRect.width - pickerRect.cursorWidthheight: 32anchors.top: pickerRect.bottomanchors.topMargin: 10anchors.left: contentText.leftgradient: Gradient {orientation: Gradient.HorizontalGradientStop { position: 0.0;  color: "#ff0000" }GradientStop { position: 0.16; color: "#ffff00" }GradientStop { position: 0.33; color: "#00ff00" }GradientStop { position: 0.5;  color: "#00ffff" }GradientStop { position: 0.76; color: "#0000ff" }GradientStop { position: 0.85; color: "#ff00ff" }GradientStop { position: 1.0;  color: "#ff0000" }}Rectangle {id: hueSliderwidth: heightheight: parent.heightanchors.verticalCenter: parent.verticalCenterborder.color: "#e6e6e6"border.width: 2scale: 0.9color: pickerRect.hueColorproperty real value: x / (parent.width - width)Behavior on scale { NumberAnimation { easing.type: Easing.OutBack; duration: 300 } }Rectangle {anchors.fill: parentanchors.margins: 1color: "transparent"border.color: "white"border.width: 2}}MouseArea {anchors.fill: parentfunction handleCursorPos(x) {let halfWidth = hueSlider.width * 0.5;hueSlider.x = Math.max(0, Math.min(width, x + halfWidth) - hueSlider.width);}onPressed: (mouse) => {hueSlider.scale = 0.6;handleCursorPos(mouse.x);}onReleased: hueSlider.scale = 0.9;onPositionChanged: (mouse) => handleCursorPos(mouse.x);}}Item {id: alphaPickerItemwidth: huePicker.widthheight: huePicker.heightanchors.top: huePicker.bottomanchors.topMargin: 25anchors.left: huePicker.leftGrid {id: alphaPickeranchors.fill: parentrows: 4columns: 29clip: trueproperty real cellWidth: width / columnsproperty real cellHeight: height / rowsRepeater {model: parent.columns * parent.rowsRectangle {width: alphaPicker.cellWidthheight: widthcolor: (index % 2 == 0) ? "gray" : "transparent"}}}Rectangle {anchors.fill: parentgradient: Gradient {orientation: Gradient.HorizontalGradientStop { position: 1.0; color: "#ff000000" }GradientStop { position: 0.0; color: "#00ffffff" }}}Rectangle {id: alphaSliderx: parent.width - widthwidth: heightheight: parent.heightanchors.verticalCenter: parent.verticalCentercolor: Qt.rgba(0.1, 0.1, 0.1, (value + 1.0) / 2.0)border.color: "#e6e6e6"border.width: 2scale: 0.9property real value: x / (parent.width - width)Behavior on scale { NumberAnimation { easing.type: Easing.OutBack; duration: 300 } }Rectangle {anchors.fill: parentanchors.margins: 1color: "transparent"border.color: "white"border.width: 1}}MouseArea {anchors.fill: parentfunction handleCursorPos(x) {let halfWidth = alphaSlider.width * 0.5;alphaSlider.x = Math.max(0, Math.min(width, x + halfWidth) - alphaSlider.width);}onPressed: (mouse) => {alphaSlider.scale = 0.6;handleCursorPos(mouse.x);}onReleased: alphaSlider.scale = 0.9;onPositionChanged: (mouse) => handleCursorPos(mouse.x);}}Button {id: confirmButtonwidth: 200height: alphaPickerItem.heightanchors.top: alphaPickerItem.bottomanchors.topMargin: 25anchors.left: alphaPickerItem.lefttext: qsTr("确定")hoverEnabled: truetopInset: down ? 1 : 0bottomInset: topInsetleftInset: topInsetrightInset: topInsetfont.family: "微软雅黑"onClicked: {root.initColor = root.currentColor;root.hide();root.accepted();}}Button {id: cancelButtonwidth: 200height: alphaPickerItem.heightanchors.top: alphaPickerItem.bottomanchors.topMargin: 25anchors.right: parent.rightanchors.rightMargin: 25text: qsTr("取消")hoverEnabled: truetopInset: down ? 1 : 0bottomInset: topInsetleftInset: topInsetrightInset: topInsetfont.family: "微软雅黑"onClicked: {pickerRect.setColor(root.initColor);root.hide();root.rejected();}}}
}

源码下载


http://www.ppmy.cn/news/1443412.html

相关文章

C++中的时间相关处理

time.h 在C11之前&#xff0c;C 程序员通常使用 C 语言标准库中的时间和日期函数来处理时间&#xff0c;这些函数的精度通常只有秒级别。这些传统的 C 语言 API 包括 time.h 头文件中定义的函数&#xff0c;如 time(), gmtime(), localtime(), mktime() 等。这些函数使用 time…

C++里的new

C里的new&#xff1a; new开辟的空间在堆上&#xff0c;而一般声明的变量存放在栈上。当在局部函数中new出一段新的空间&#xff0c;该段空间在局部函数调用结束后仍然能够使用&#xff0c;可以用来向主函数传递参数。new出来的是一段空间的首地址。所以一般需要用指针来存放这…

AngularJS中文手册前半部分学习

AngularJS 简介 AngularJS的中文参考手册 AngularJS的使用 AngularJS 是一个JS框架&#xff0c;通过指令(ng-directives)扩展了HTML&#xff0c;且通过表达式绑定数据到HTML&#xff0c;用于开发单一页面应用程序&#xff08;SPAs&#xff1a;Single Page Applications&…

六.音视频编辑-创建视频过渡-概述

引言 目前我的应用已经实现了视频的编辑&#xff0c;音频的混合处理。随着时间的推进&#xff0c;两个不同场景的视频快速的切换&#xff0c;其中没有任何过渡效果。通常画面在时间轴上出现明显的变化时&#xff0c;两个场景间会使用一些动画的过渡效果。比如渐隐&#xff0c;…

Android如何使用XML自定义属性

1、定义 在res/values文件下定义一个attrs.xml文件&#xff0c;代码如下: 2、使用 在布局中使用&#xff0c; 示例代码如下&#xff1a; 3、获取 最终来到这里&#xff1a;

Android Binder——APP中AIDL解析(二十)

上一篇我们最后运行了项目,并完成了跨进成通信。这里我们就来以 getTitleText() 为例分析一下调用流程。 一、调用流程 首先,我们在 bindService 成功回调 onServiceConnected 中,通过 IMyAidlInterface.Stub.asInterface() 获取 Binder 的代理对象。对应方法在 IMyAidlInt…

应用在隔离的IGBT模块中的光电耦合器

IGBT(Insulated Gate Bipolar Transistor)&#xff0c;绝缘栅双极型晶体管&#xff0c;是由BJT(双极型三极管)和MOS(绝缘栅型场效应管)组成的复合全控型电压驱动式功率半导体器件, 兼有MOSFET的高输入阻抗和GTR的低导通压降两方面的优点。GTR饱和压降低&#xff0c;载流密度大&…

人工智能(pytorch)搭建模型28-基于Transformer的端到端目标检测DETR模型的实际应用,DETR的原理与结构

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型28-基于Transformer的端到端目标检测DETR模型的实际应用&#xff0c;DETR的原理与结构。DETR&#xff08;Detected Transformers&#xff09;是一种基于Transformer的端到端目标检测模型&…