一、前言

相比于上一个颜色按钮面板,此控件就要难很多,颜色值有三种表示形式,除了程序员最常用的RGB以外,还有HSB和CMY方式。

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。也是程序员最喜欢最常用的颜色表示方法。

HSB又称HSV,表示一种颜色模式:在HSB模式中,H(hues)表示色相,S(saturation)表示饱和度,B(brightness)表示亮度HSB模式对应的媒介是人眼。HSB模式中S和B呈现的数值越高,饱和度明度越高,页面色彩强烈艳丽,对视觉刺激是迅速的,醒目的效果,但不益于长时间的观看。

CMY是青(Cyan)、洋红或品红(Magenta)和黄(Yellow)三种颜色的简写,是相减混色模式,用这种方法产生的颜色之所以称为相减色,乃是因为它减少了为视觉系统识别颜色所需要的反射光。

由于本控件用于灯光舞台效果的控制控件,可能用户不一定相关使用RGB颜色,也可能用到HSB或者CMY,所以在提供颜色选择的时候,三种都要提供,一种处于选中调节模式的情况下,另外两种要跟随变化,这个是难点,要不断计算当前的颜色值换算成其他颜色值,一开始采用了各种公式换算,后面发现原来QColor内部就封装了,我擦,比如QColor::fromHsv,QColor::fromRgb等,真的是非常强大,可以不用管具体的换算细节。

二、实现的功能

  • 1:可设置滑块条之间的间隔
  • 2:可设置滑块组之间的间隔
  • 3:可设置背景颜色

三、效果图

四、头文件代码

#ifndef COLORPANELFADER_H
#define COLORPANELFADER_H /**
* 颜色滑块面板 作者:feiyangqingyun(QQ:517216493) 2017-11-17
* 1:可设置滑块条之间的间隔
* 2:可设置滑块组之间的间隔
* 3:可设置背景颜色
*/ #include <QWidget> class QHBoxLayout;
class QSpacerItem;
class ColorPanelBar; #ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif class QDESIGNER_WIDGET_EXPORT ColorPanelFader : public QWidget
#else
class ColorPanelFader : public QWidget
#endif {
Q_OBJECT
Q_PROPERTY(int barSpace READ getBarSpace WRITE setBarSpace)
Q_PROPERTY(int groupSpace READ getGroupSpace WRITE setGroupSpace)
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor) public:
explicit ColorPanelFader(QWidget *parent = 0); protected:
bool eventFilter(QObject *watched, QEvent *event);
void paintEvent(QPaintEvent *); private:
QHBoxLayout *layout;
QSpacerItem *spacer1;
QSpacerItem *spacer2;
QList<ColorPanelBar *> items; int barSpace; //柱状条间隔
int groupSpace; //分组间隔
QColor bgColor; //背景颜色 private slots:
void colorChanged(const QColor &color, double value, double percent); public:
int getBarSpace() const;
int getGroupSpace() const;
QColor getBgColor() const; QSize sizeHint() const;
QSize minimumSizeHint() const; public:
//设置柱状条间隔
void setBarSpace(int barSpace);
//设置分组间隔
void setGroupSpace(int groupSpace);
//设置背景颜色
void setBgColor(const QColor &bgColor); Q_SIGNALS:
void colorChanged(const QColor &color, double hue, double sat, double bright);
}; #endif // COLORPANELFADER_H

五、核心代码

bool ColorPanelFader::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) {
ColorPanelBar *item = (ColorPanelBar *)watched;
int index = items.indexOf(item);
if (index >= 6) {
items.at(0)->setEnabled(false);
items.at(1)->setEnabled(false);
items.at(2)->setEnabled(false);
items.at(3)->setEnabled(false);
items.at(4)->setEnabled(false);
items.at(5)->setEnabled(false);
} else if (index >= 3) {
items.at(0)->setEnabled(false);
items.at(1)->setEnabled(false);
items.at(2)->setEnabled(false);
items.at(6)->setEnabled(false);
items.at(7)->setEnabled(false);
items.at(8)->setEnabled(false);
} else if (index >= 0) {
items.at(3)->setEnabled(false);
items.at(4)->setEnabled(false);
items.at(5)->setEnabled(false);
items.at(6)->setEnabled(false);
items.at(7)->setEnabled(false);
items.at(8)->setEnabled(false);
}
} else if (event->type() == QEvent::MouseButtonRelease) {
ColorPanelBar *item = (ColorPanelBar *)watched;
int index = items.indexOf(item);
if (index >= 6) {
items.at(0)->setEnabled(true);
items.at(1)->setEnabled(true);
items.at(2)->setEnabled(true);
items.at(3)->setEnabled(true);
items.at(4)->setEnabled(true);
items.at(5)->setEnabled(true);
} else if (index >= 3) {
items.at(0)->setEnabled(true);
items.at(1)->setEnabled(true);
items.at(2)->setEnabled(true);
items.at(6)->setEnabled(true);
items.at(7)->setEnabled(true);
items.at(8)->setEnabled(true);
} else if (index >= 0) {
items.at(3)->setEnabled(true);
items.at(4)->setEnabled(true);
items.at(5)->setEnabled(true);
items.at(6)->setEnabled(true);
items.at(7)->setEnabled(true);
items.at(8)->setEnabled(true);
}
} return QWidget::eventFilter(watched, event);
} void ColorPanelFader::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), bgColor);
} void ColorPanelFader::colorChanged(const QColor &color, double value, double percent)
{
ColorPanelBar *item = (ColorPanelBar *)sender();
int index = items.indexOf(item); if (index == 0) {
//获取当前HSB处的颜色值
items.at(1)->setTopColor(color);
items.at(2)->setTopColor(color);
items.at(1)->setBorderColor(color);
items.at(2)->setBorderColor(color);
} else if (index == 1) {
items.at(2)->setTopColor(color);
items.at(2)->setBorderColor(color);
} else if (index == 2) {
items.at(1)->setTopColor(color);
items.at(1)->setBorderColor(color);
} else if (index == 3) {
items.at(6)->setPercent(100 - percent);
} else if (index == 4) {
items.at(7)->setPercent(100 - percent);
} else if (index == 5) {
items.at(8)->setPercent(100 - percent);
} else if (index == 6) {
items.at(3)->setPercent(100 - percent);
} else if (index == 7) {
items.at(4)->setPercent(100 - percent);
} else if (index == 8) {
items.at(5)->setPercent(100 - percent);
} //如果是HSB变化则CMY和RGB变化
if (index < 3) {
double hue = items.at(0)->getPercent() / 100;
double sat = items.at(1)->getPercent() / 100;
double bright = items.at(2)->getPercent() / 100; //组合HSB当前值,然后转为CMY和RGB计算百分比进行设置
QColor color = QColor::fromHsvF(hue, sat, bright);
double percentRed = color.redF() * 100;
double percentGreen = color.greenF() * 100;
double percentBlue = color.blueF() * 100; items.at(3)->setPercent(100 - percentRed);
items.at(4)->setPercent(100 - percentGreen);
items.at(5)->setPercent(100 - percentBlue);
items.at(6)->setPercent(percentRed);
items.at(7)->setPercent(percentGreen);
items.at(8)->setPercent(percentBlue);
} //根据百分比获取颜色值
double red = items.at(6)->getPercent() / 100;
double green = items.at(7)->getPercent() / 100;
double blue = items.at(8)->getPercent() / 100;
QColor currentColor = QColor::fromRgbF(red, green, blue);
emit colorChanged(currentColor, items.at(0)->getValue(), items.at(1)->getPercent(), items.at(2)->getPercent()); //如果是CMY或者RGB变化则HSB变化
if (index >= 3) {
//hue活出现负数=白色,要矫正
double percentHue = currentColor.hueF() * 100;
if (percentHue < 0) {
percentHue = 0;
} double percentSat = currentColor.saturationF() * 100;
double percentBright = currentColor.lightnessF() * 100; //计算当前值所占百分比
items.at(0)->setPercent(percentHue);
items.at(1)->setPercent(percentSat);
items.at(2)->setPercent(percentBright); items.at(1)->setTopColor(currentColor);
items.at(2)->setTopColor(currentColor);
items.at(1)->setBorderColor(currentColor);
items.at(2)->setBorderColor(currentColor);
}
}

六、控件介绍

  1. 超过149个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
  2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
  3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
  4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
  5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
  6. 每个控件默认配色和demo对应的配色都非常精美。
  7. 超过130个可见控件,6个不可见控件。
  8. 部分控件提供多种样式风格选择,多种指示器样式选择。
  9. 所有控件自适应窗体拉伸变化。
  10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
  11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
  12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
  13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。
  14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。

七、SDK下载

  • SDK下载链接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取码:877p
  • 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo,自定义控件+属性设计器。
  • 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
  • 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
  • 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
  • widget版本(QQ:517216493)qml版本(QQ:373955953)三峰驼(QQ:278969898)。
  • 涛哥的知乎专栏 Qt进阶之路 https://zhuanlan.zhihu.com/TaoQt
  • 欢迎关注微信公众号【高效程序员】,C++/Python、学习方法、写作技巧、热门技术、职场发展等内容,干货多多,福利多多!

Qt编写自定义控件28-颜色滑块面板的更多相关文章

  1. Qt编写自定义控件29-颜色选取面板

    一.前言 这个控件主要是模仿QColorDialog对话框中的颜色选取面板,提供一个十字形状的标识器,鼠标按下开始选取颜色,移动到哪就选择该处的颜色值,对应右侧颜色条放大显示,本控件的难点就是如何绘制 ...

  2. Qt编写自定义控件27-颜色按钮面板

    一.前言 颜色按钮面板主要用在提供一个颜色按钮面板,用户单击某个按钮,然后拿到对应的颜色值,用户可以预先设定常用的颜色集合,传入到控件中,自动生成面板颜色集合按钮,每当滑过按钮的时候,按钮边缘高亮提示 ...

  3. Qt编写自定义控件二动画按钮

    现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...

  4. Qt编写自定义控件10-云台仪表盘

    前言 做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程 ...

  5. Qt编写自定义控件70-扁平化flatui

    一.前言 对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反 ...

  6. Qt编写自定义控件59-直方动态图

    一.前言 直方动态图类似于音乐播放时候的柱状图展示,顶部提供一个横线条,当柱状上升的时候,该线条类似于帽子的形式冲到顶端,相当于柱状顶上去的感觉,给人一种动态的感觉,听音乐的同时更加赏心悦目,原理比较 ...

  7. Qt编写自定义控件56-波浪曲线

    一.前言 波浪曲线控件,其实是之前一个水波进度条控件的一个核心,其实就是利用正弦曲线来生成对应的坐标进行绘制,把这个功能单独提取出来,是为了更详细的研究各种正弦余弦等拓展效果,当时写这个效果的时候,参 ...

  8. Qt编写自定义控件55-手机通讯录

    一.前言 前面几篇文章中的控件基本上难度系数接近0,甚至有凑控件数量的嫌疑,这次必须来一个强悍的控件,本控件难度系数在所有控件中排前五,代码量也不少,头文件都550行,实现文件1600行,为什么这么多 ...

  9. Qt编写自定义控件48-面板窗体控件

    一.前言 很多时候需要有一个控件,能够替代容器控件,自动容纳多个widget,自适应宽高,然后提供滚动条功能,这就必然需要用到QScrollArea控件,可设置各个子面板的间距等,也在很多系统中用到, ...

随机推荐

  1. 【问题】为啥WMWare Workstation里面虚拟机的网关默认是NAT网关

    今天做KickStart自动化安装实验,无意中发现一个奇怪现象. 先描述下我的实验环境:笔记本Win10,安装了WMWare Workstation,在WMWare Workstation上面安装了C ...

  2. 08_Azkaban案例实践1_Command单一job示例

    1.Azkaban实战 Azkaba内置的任务类型支持command.java 2.Command类型单一job示例 1.创建job描述文件:vi command.job #command.job t ...

  3. API接口文档中将Swagger文档转Word 文档

    一般的开发工作,尤其是API接口的开发工作,首先要有开发文档,接口说明文档 ok,后来开发完毕了 和页面联调,或者是和第三方联调的时候, 这个时候,SA systeam admin 就会开始直接让开发 ...

  4. #Python绘制 文本进度条,带刷新、时间暂缓的

    #Python绘制 文本进度条,带刷新.时间暂缓的 #文本进度条 import time as T st=T.perf_counter() print('-'*6,'执行开始','-'*6) maxx ...

  5. golang中fmt的'占位符'使用

    golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf. # 定义示例类型和变量 type Human struct { Name string } var peo ...

  6. Java并发包--ArrayBlockingQueue

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3498652.html ArrayBlockingQueue介绍 ArrayBlockingQueue是数 ...

  7. c语言学习、工作相关必备的常用网站

    1.https://zh.cppreference.com/,c.c++参考手册, 2.http://www.cplusplus.com/,在线查看c.c++函数的定义及用法 3.http://c-f ...

  8. Linq to AD

    輕鬆找出域中所有用戶,組,而且還可以更改 LINQ to Active Directory https://linqtoad.codeplex.com/ LINQ to LDAP http://lin ...

  9. wamp大文件上传

    为什么上传大文件总是失败,但是上传小文件就没有问题.小编也不得其解,网上搜其原因,整理了一篇关于php上传大文件失败的原因和解决办法的文章,分享给大家. 下面分别是各种原因以及解决办法:第1种情况:文 ...

  10. classpath详解

    在dos下编译java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候.classpath就是存放.class等编译后文件的路径. javac:如果当前你要编译的java文件中 ...