百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

Qt——设计颜色编辑选取对话框(qt颜色选择框)

ztj100 2025-04-08 20:52 11 浏览 0 评论

Qt中已经有一些封装好的对话框,比如QMessageBox、QColorDialog等,使用起来快捷方便,但缺点是我们无法为它们自定义样式,所以可能难以“融入”我们的项目。既然如此,那就自己做一个把。抱着这样的想法,我设计了一个颜色编辑选取对话框。

设计界面时,我参考了photoshop的拾色器、windows的画图软件以及一个手绘控件软件mockup。

最终完成的界面如下:

它包括以下一些功能:

  • 选取预设的基本颜色
  • 添加自定义颜色方便下次选取
  • 从颜色拾取区域选择颜色
  • 预览当前颜色和新选择的颜色
  • 查看和编辑调整颜色的hsv、rgb和16进制值

下面对一些重点难点作相关介绍:

一、色调、饱和度、亮度

从上图可以看到,右边的矩形是调整色调的区域,这部分亮度和饱和度都是100%,色调值由下往上递增,范围是0-360。

左边的正方形区域是在某个色调值下,调整饱和度和亮度。亮度由下往上递增,饱和度由左往右递增。

色调(Hue)、饱和度(Saturation)、亮度(Brightness或Value)三者决定一个颜色(注:这里不考虑透明度),也就是我们所说的hsv。

同样地,一个颜色可以用hsv表示,也可以用RGB来表示。

根据上面的原理,设计相关算法也就不难了。

1.色调

m_huePixmap = QPixmap(34, 270);

m_huePixmap.fill(Qt::transparent);

QPainter painter(&m_huePixmap);

painter.setRenderHint(QPainter::Antialiasing);

QLinearGradient hueGradient(0, m_iColorHeight, 0, 0);

for (double i = 0; i < 1.0; i += 1.0 / 16)

{

hueGradient.setColorAt(i, QColor::fromHsvF(i, 1, 1, 1));

}

hueGradient.setColorAt(1, QColor::fromHsvF(0, 1, 1, 1));

painter.setPen(Qt::NoPen);

painter.setBrush(QBrush(hueGradient));

painter.drawRect(0, topMargin, m_iColorWidth, m_iColorHeight);

请原谅代码中一些费解的变量和值。

在这里,我们使用的是QLinearGeadient渐变来画一个pixmap,由下往上,饱和度百分值由0增加到1.0。

2.饱和度、亮度

一开始我的想法是这个问题能不能像色调一样,也用渐变来解决,但是并没有想到合适的办法。

于是只能遍历每个像素并设置颜色,一共遍历了256 * 256次!

for (int i = 0; i <= 255; ++i)

{

uchar *colorUnit = m_svImg.scanLine(i);

for (int j = 0; j <= 255; ++j)

{

color.setHsv(m_iHue, j, 255 - i);

QRgb curRgb = color.rgb();

colorUnit[j * 4] = qBlue(curRgb);

colorUnit[j * 4 + 1] = qGreen(curRgb);

colorUnit[j * 4 + 2] = qRed(curRgb);

colorUnit[j * 4 + 3] = 255;

}

}

QImage有一个函数setPixel,设置每一个像素点的Rgb值,但是该函数效率很低。根据qt给出的建议,使用scanLine()这个函数

一开始我用的是QPixmap,但发现并没有设置像素颜色的函数,于是换成了QImage。

当时还找了别人写的一些颜色编辑器demo,发现他们居然都用的setPixel,效率之低难以置信。于是硬着头皮在Qt文档中找答案,最终找到了scanLine,效率提高了不少。

但是遍历256*256次总让人感觉不那么自在!

~

~

~

直到有一天,灵光一现。在这个正方形区域中,同一垂直线上的色调值和饱和度值是一样的,同一水平线上的色调值和亮度值是一样的。那么从左往右是从白色#ffffff到当前色调区域所选颜色的渐变,由上往下可以是一个透明度从0到255的渐变。将二者结合起来,正好得到了我想要的。或许,这就是缘分吧:

//1

QLinearGradient svGradient(0, 0, m_iAreaWidth, 0);

svGradient.setColorAt(1, newColor);

svGradient.setColorAt(0, QColor("#ffffff"));

//2

QLinearGradient vGradient(0, 0, 0, m_iAreaWidth);

vGradient.setColorAt(0, QColor(0, 0, 0, 0));

vGradient.setColorAt(1, QColor(0, 0, 0, 255));

//最后将两个Pixmap重合

通过“肉眼”的观察,能明显感觉到效率提高了很多很多!

二、逻辑问题

另一大难点就是逻辑问题,界面中各个区域有一个改变,就可能引起其它所有区域的改变。

比如:色调改变 - 饱和度亮度区域需要重绘 - 颜色预览区域新的颜色改变 - 16进制文本编辑框和RGB、HSV的spinbox都会随之改变

正所谓“牵一发而动全身”,更复杂的是,这些控件是相互影响的!

如果思考不周,将导致程序逻辑混乱、程序出现死循环或者多次循环影响效率等问题。

我在写这个程序时主要用了3种方法避免混乱:

1.通过信号槽连接传递变化

2.调用其它类的公有函数

3.设置“flag”,通过判断它的布尔值来决定是否调用函数。

第2和第3都是为了防止信号槽传递时可能导致程序的混乱。

三、关于QLineEdit的思考

左边的lineEdit中展示的是颜色RGB值的16进制形式,范围000000-ffffff,可以通过正则表达式对使用者的输入进行限制。也可以加上inputMask,对格式进行更加严格的限制。然而限制太多反而会影响用户体验,需慎重考虑。

我的做法如下:

1.使用正则表达式控制输入范围。

2.手动编辑lineEdit中的内容时,光标位于lineEdit中,捕获textEdited信号,改变颜色值。

3.鼠标点击界面其它部分,使lineEdit失去焦点,然后捕获它的编辑结束editingFinished信号,使其中的文本恢复6位的格式。

为了使鼠标点击界面其它部分时输入框失去焦点,需要设置主窗口的focus属性:

setFocusPolicy(Qt::ClickFocus);

在设计这部分时,我也参考了photoshop的方法,可以打开ps感受一下哦。

源码放在了github上,请原谅其中一些蹩脚的代码,因为最初使用Qt4编写的,后来在Qt5上运行也就没怎么修改。

相关推荐

其实TensorFlow真的很水无非就这30篇熬夜练

好的!以下是TensorFlow需要掌握的核心内容,用列表形式呈现,简洁清晰(含表情符号,<300字):1.基础概念与环境TensorFlow架构(计算图、会话->EagerE...

交叉验证和超参数调整:如何优化你的机器学习模型

准确预测Fitbit的睡眠得分在本文的前两部分中,我获取了Fitbit的睡眠数据并对其进行预处理,将这些数据分为训练集、验证集和测试集,除此之外,我还训练了三种不同的机器学习模型并比较了它们的性能。在...

机器学习交叉验证全指南:原理、类型与实战技巧

机器学习模型常常需要大量数据,但它们如何与实时新数据协同工作也同样关键。交叉验证是一种通过将数据集分成若干部分、在部分数据上训练模型、在其余数据上测试模型的方法,用来检验模型的表现。这有助于发现过拟合...

深度学习中的类别激活热图可视化

作者:ValentinaAlto编译:ronghuaiyang导读使用Keras实现图像分类中的激活热图的可视化,帮助更有针对性...

超强,必会的机器学习评估指标

大侠幸会,在下全网同名[算法金]0基础转AI上岸,多个算法赛Top[日更万日,让更多人享受智能乐趣]构建机器学习模型的关键步骤是检查其性能,这是通过使用验证指标来完成的。选择正确的验证指...

机器学习入门教程-第六课:监督学习与非监督学习

1.回顾与引入上节课我们谈到了机器学习的一些实战技巧,比如如何处理数据、选择模型以及调整参数。今天,我们将更深入地探讨机器学习的两大类:监督学习和非监督学习。2.监督学习监督学习就像是有老师的教学...

Python教程(三十八):机器学习基础

...

Python 模型部署不用愁!容器化实战,5 分钟搞定环境配置

你是不是也遇到过这种糟心事:花了好几天训练出的Python模型,在自己电脑上跑得顺顺当当,一放到服务器就各种报错。要么是Python版本不对,要么是依赖库冲突,折腾半天还是用不了。别再喊“我...

超全面讲透一个算法模型,高斯核!!

...

神经网络与传统统计方法的简单对比

传统的统计方法如...

AI 基础知识从0.1到0.2——用“房价预测”入门机器学习全流程

...

自回归滞后模型进行多变量时间序列预测

下图显示了关于不同类型葡萄酒销量的月度多元时间序列。每种葡萄酒类型都是时间序列中的一个变量。假设要预测其中一个变量。比如,sparklingwine。如何建立一个模型来进行预测呢?一种常见的方...

苹果AI策略:慢哲学——科技行业的“长期主义”试金石

苹果AI策略的深度原创分析,结合技术伦理、商业逻辑与行业博弈,揭示其“慢哲学”背后的战略智慧:一、反常之举:AI狂潮中的“逆行者”当科技巨头深陷AI军备竞赛,苹果的克制显得格格不入:功能延期:App...

时间序列预测全攻略,6大模型代码实操

如果你对数据分析感兴趣,希望学习更多的方法论,希望听听经验分享,欢迎移步宝藏公众号...

AI 基础知识从 0.4 到 0.5—— 计算机视觉之光 CNN

...

取消回复欢迎 发表评论: