Qt自定义ColorDialog(支持RGB和HSV)

当我们做软件开发的时候,经常需要编辑颜色,有时需要同时编辑RGB和HSV的颜色。

这是一个自定义的颜色对话框,如下图所示

具有如下功能:

  1. 支持RGB和HSV颜色值得修改和预览
  2. 支持添加自定义颜色(点击按钮添加或鼠标拖拽添加)

修改颜色效果预览:

添加自定义颜色效果预览:

颜色控件效果预览:

下面是主要用到得技术点说明


1. HSV和RGB

RGB想必大家都不陌生,但是实际生活中更为常用的是HSV颜色空间
H: 表示 色调 ,取值为0~359,使用度数表示它的值,0度为红色,120度为绿色,240度为蓝色。

S: 表示色彩的 饱和度 ,取值范围为0~255,饱和度值越大,他的颜色就越丰满。
V: 表示 亮度 ,取值范围为0~255,0为黑色,值越大则约明亮。

Qt中使用 QColor 类可以方便的设置和获取RGB颜色和YUV颜色值:

  • 函数 getRgb()rgb() 可以设置和获取RGB颜色值
  • 函数 setHsv()getHsv() 可以设置和获取HSV颜色值

2. H分量圆盘绘制

因为H分量是根据度数决定的,这里使用类 QConicalGradient 设置画刷来绘制渐变效果,

关键代码如下:

QConicalGradient conicalGradient(this->rect().center(), 0);
qreal interval = 1.0 / m_colorVec.size();
// 设置渐变颜色
for (int i=0; i<m_colorVec.size(); ++i)
{
    conicalGradient.setColorAt(interval * i, m_colorVec[i]);
}
conicalGradient.setColorAt(1.0, m_colorVec[0]);

// 绘制圆环
painter->setBrush(conicalGradient);
painter->setPen(QPen(Qt::NoPen));
int width = qMin(this->width(), this->height()) / 2 * 2;
QRect centerRect(this->rect().center().x() - width / 2, \
                 this->rect().center().y() - width / 2, \
                 width, width);
painter->drawEllipse(centerRect);

渐变位置值设置范围为 0~1 ,其中 m_colorVec 是一个 QVector<QColor> 类型的成员变量

初始化代码如下:

m_colorVec << QColor(255, 0, 0) << QColor(255, 255, 0) \
           << QColor(0, 255, 0) << QColor(0, 255, 255) \
           << QColor(0, 0, 255) << QColor(255, 0, 255);

分别对应上图 0~360度的颜色值。


3. SV画布绘制

画布的 X轴从左到右表示S值从0~255
Y轴从下到上表示V值从0~255
如下所示:

绘制方法:

  1. 先绘制从最左侧颜色值为白色RGB(255,255,255)到最右侧HSV(h,255,255)的渐变
  2. 再绘制从最顶部颜色值为RGBA(0, 0, 0, 0)到最底部RGBA(0, 0, 0, 255)的渐变

关键代码如下:

// 绘制从左到右RGB(255,255,255)到HSV(h,255,255)的渐变
QLinearGradient linearGradientH(rect.topLeft(), rect.topRight());
linearGradientH.setColorAt(0, QColor(255, 255, 255));
QColor color;
color.setHsv(m_nHValue, 255, 255);
linearGradientH.setColorAt(1, color);
painter->fillRect(rect, linearGradientH);

// 绘制顶部颜色值为RGBA(0,0,0,0)到最底部RGBA(0,0,0,255)的渐变
QLinearGradient linearGradientV(rect.topLeft(), rect.bottomLeft());
linearGradientV.setColorAt(0, QColor(0, 0, 0, 0));
linearGradientV.setColorAt(1, QColor(0, 0, 0, 255));
painter->fillRect(rect, linearGradientV);
不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:基于Qt的简易Http下载软件