Qt环形颜色选择控件, 圆环颜色选择器

参考文章Qt编写自定义控件:环形颜色选择控件_qconicalgradient圆环渐变-CSDN博客

感谢作责提供的方法,下面程序的基础思路同参考文章。

为了更方便使用,这个选择器是基于64色表的,会显示选中的索引和色值。颜色选择时计算方式也有所不同。

选择器是逆时针的,先将64色填入渐变。通过根据小原型的位置,计算出角度,然后计算出它占360度的百分比,然后算出对应的索引,通过索引获得颜色,然后通知出去。

代码如下:

#include <QList>
#include <QColor>

const QList<QColor> listColor{
    QColor(0x72, 0x70, 0x1C),   //0
    QColor(0x6B, 0x72, 0x23),
    QColor(0x57, 0x76, 0x32),
    QColor(0x57, 0x6D, 0x3B),
    QColor(0x49, 0x61, 0x55),
    QColor(0x4B, 0x51, 0x63),
    QColor(0x46, 0x32, 0x87),
    QColor(0x3F, 0x12, 0xAE),   //7

    QColor(0x3F, 0x00, 0xC0),   //8
    QColor(0x5B, 0x0C, 0x98),
    QColor(0x68, 0x1D, 0x7A),
    QColor(0x7A, 0x36, 0x4F),
    QColor(0x8A, 0x20, 0x55),
    QColor(0x9C, 0x1E, 0x45),
    QColor(0xA7, 0x07, 0x51),
    QColor(0xB9, 0x13, 0x33),

    QColor(0xD1, 0x1E, 0x20),   //16
    QColor(0xC0, 0x2C, 0x13),
    QColor(0xDF, 0x13, 0x0D),
    QColor(0xFF, 0x00, 0x00),
    QColor(0xFD, 0x02, 0x00),
    QColor(0xFB, 0x02, 0x02),
    QColor(0xF1, 0x02, 0x0C),
    QColor(0xDB, 0x19, 0x0B),

    QColor(0xE4, 0x01, 0x1A),   //24
    QColor(0xC9, 0x06, 0x30),
    QColor(0x9D, 0x03, 0x5F),
    QColor(0x78, 0x06, 0x81),
    QColor(0x61, 0x04, 0x9A),
    QColor(0x48, 0x06, 0xB1),
    QColor(0x34, 0x03, 0xC8),
    QColor(0x2C, 0x05, 0xCF),

    QColor(0x24, 0x02, 0xD9),   //32
    QColor(0x00, 0x00, 0xFF),
    QColor(0x17, 0x01, 0xE7),
    QColor(0x1F, 0x01, 0xDF),
    QColor(0x20, 0x0F, 0xD0),
    QColor(0x30, 0x44, 0x8b),
    QColor(0x33, 0x78, 0x54),
    QColor(0x3A, 0x86, 0x3F),

    QColor(0x14, 0x82, 0x69),   //40
    QColor(0x18, 0x9B, 0x4C),
    QColor(0x0A, 0xBB, 0x3A),
    QColor(0x06, 0xE0, 0x19),
    QColor(0x1F, 0xC3, 0x1D),
    QColor(0x37, 0xB2, 0x16),
    QColor(0x1D, 0xDB, 0x08),
    QColor(0x00, 0xFF, 0x00),

    QColor(0x0F, 0xEE, 0x02),   //48
    QColor(0x34, 0xC9, 0x02),
    QColor(0x5D, 0xA0, 0x02),
    QColor(0x8D, 0x71, 0x01),
    QColor(0xA6, 0x58, 0x01),
    QColor(0xB9, 0x46, 0x00),
    QColor(0xD7, 0x28, 0x33),
    QColor(0xC9, 0x33, 0x03),
    
    QColor(0xDF, 0x1B, 0x05),   //56
    QColor(0xD5, 0x25, 0x05),
    QColor(0xC5, 0x35, 0x05),
    QColor(0xB0, 0x45, 0x0A),
    QColor(0x96, 0x5F, 0x0A),
    QColor(0x8A, 0x66, 0x0F),
    QColor(0x82, 0x6A, 0x13),
    QColor(0x7C, 0x6C, 0x18)    //63
};  //0-63(64色)
#ifndef COLORSELECTIONCIRCLE_H
#define COLORSELECTIONCIRCLE_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class ColorSelectionCircle; }
QT_END_NAMESPACE

class ColorSelectionCircle : public QWidget
{
    Q_OBJECT

public:
    ColorSelectionCircle(QWidget *parent = nullptr);
    ~ColorSelectionCircle();

protected:
    void paintEvent(QPaintEvent *event)override;
    void mousePressEvent(QMouseEvent *event)override;
    void mouseReleaseEvent(QMouseEvent *event)override;
    void mouseMoveEvent(QMouseEvent *event)override;
    void showEvent(QShowEvent *event) override;

signals:
    void ColorInfo(int index, QColor color);


private:
    qreal ballAngle{0};
    bool isPressed{false};
    void getColorInWidget(const QPoint &pos);
    QColor selectColor;//
   
    int m_index{0};

private:
    Ui::ColorSelectionCircle *ui;
};
#endif // COLORSELECTIONCIRCLE_H
#include "colorselectioncircle.h"
#include "ui_colorselectioncircle.h"
#include <QPaintEvent>
#include <QPainterPath>
#include <QDebug>
#include <QtMath>
#include <QGuiApplication>
#include <QScreen>
#include <QPainter>
#include "commondata.h"

ColorSelectionCircle::ColorSelectionCircle(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ColorSelectionCircle)
{
    ui->setupUi(this);
    setPalette(Qt::white);
    setMinimumSize(150, 150);


}

ColorSelectionCircle::~ColorSelectionCircle()
{
    delete ui;
}

void ColorSelectionCircle::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        auto pressPos = event->pos();
        QPoint centerPoint = rect().center();
        
        ballAngle = -atan2(pressPos.y() - centerPoint.y(), pressPos.x() - centerPoint.x()) * (180 / M_PI);
        
        if(ballAngle < 0)
        {
            ballAngle = ballAngle + 360;
        }

        auto tmpballAngle = ((int)(ballAngle + 360.0 / listColor.size() / 2)) % 360 ;
        m_index = tmpballAngle / 360.0 * listColor.size();
        
        isPressed = true;
        emit ColorInfo(m_index, listColor[m_index]);
        update();
    }
    QWidget::mousePressEvent(event);
}

void ColorSelectionCircle::mouseReleaseEvent(QMouseEvent *event)
{
    if (isPressed)
    {
        isPressed = false;
    }
    return QWidget::mouseReleaseEvent(event);
}

void ColorSelectionCircle::mouseMoveEvent(QMouseEvent* event)
{
    if (isPressed)
    {
        auto nowPos = event->pos();
        QPoint centerPoint = rect().center();
        ballAngle = -atan2(nowPos.y() - centerPoint.y(), nowPos.x() - centerPoint.x()) * (180 / M_PI);
        //qDebug()<<"ballAngle:"<<ballAngle;
        if(ballAngle < 0)
        {
            ballAngle = ballAngle + 360;
        }
        auto tmpballAngle = ((int)(ballAngle + 360.0 / listColor.size() / 2))%360 ;
        

        //qDebug()<<"ballAngle after:"<<tmpballAngle;
        
        m_index = tmpballAngle / 360.0 * listColor.size();

        emit ColorInfo(m_index, listColor[m_index]);
        update();
    }
    return QWidget::mouseMoveEvent(event);
}

void ColorSelectionCircle::showEvent(QShowEvent *event)
{
    emit ColorInfo(m_index, listColor[m_index]);
    update();
    return QWidget::showEvent(event);
}

void ColorSelectionCircle::getColorInWidget(const QPoint &pos)
{
    static QScreen *screen = QGuiApplication::screenAt(pos);
    if (!screen)
    {
        screen = QGuiApplication::primaryScreen();
    }
    auto gpos = mapToGlobal(pos);
    selectColor = screen->grabWindow(0, gpos.x(), gpos.y(), 1, 1).toImage().pixel(0, 0);
}

void ColorSelectionCircle::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::transparent);

    auto rect = event->rect();
    auto standardLength = std::min(rect.width(), rect.height());
    auto radius = standardLength / 2 - standardLength * 0.1;
    QConicalGradient conicalGradient(0, 0, 0);


    for (int i=0; i<listColor.size(); ++i)
    {
        auto pos = 1.0 * i / listColor.size();
        
        conicalGradient.setColorAt(pos, listColor[i]);
    }
    conicalGradient.setColorAt(1.0, listColor[0]);
    painter.translate(rect.center());

    QBrush brush(conicalGradient);
    painter.setPen(Qt::NoPen);
    painter.setBrush(brush);

    QPainterPath path1;
    path1.addEllipse(QPoint(0, 0), radius, radius);

    QPainterPath path2;
    path2.addEllipse(QPoint(0, 0), radius * 0.8, radius* 0.8);
    painter.drawPath(path1- path2);

    QPointF ballPos = QPointF(cos(ballAngle * M_PI/180)*radius*0.9, -sin(ballAngle*M_PI/180)*radius*0.9);
    painter.setPen(QColor(0xff, 0xff, 0xff));
    painter.drawEllipse(ballPos, radius*0.2, radius*0.2);
    painter.setBrush(listColor[m_index]);

}
#include "colorselect.h"
#include "ui_colorselect.h"
#include <QPalette>

ColorSelect::ColorSelect(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ColorSelect)
{
    ui->setupUi(this);
    this->setWindowTitle(QString("Color Selector"));
    connect(ui->widget, SIGNAL(ColorInfo(int,QColor)), this, SLOT(ColorInfoProcess(int,QColor)));
}

ColorSelect::~ColorSelect()
{
    delete ui;
}

void ColorSelect::ColorInfoProcess(int index, QColor color)
{
    ui->lineEdit_index->setText(QString("%1").arg(index));
    ui->lineEdit_RGB->setText(color.name());
    QPalette pe;

    pe.setColor(ui->label_color->backgroundRole(), color);
    ui->label_color->setAutoFillBackground(true);
    ui->label_color->setPalette(pe);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522084.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 Pandas 中的 groupby 函数

groupby 函数是 pandas 库中 DataFrame 和 Series 对象的一个方法&#xff0c;它允许你对这些对象中的数据进行分组和聚合。下面是 groupby 函数的一些常用语法和用法。 对于 DataFrame 对象&#xff0c;groupby 函数的语法如下&#xff1a; DataFrame.groupby(byNone, axis0…

面试(03)————多线程和线程池

一、多线程 1、什么是线程?线程和进程的区别? 2、创建线程有几种方式 &#xff1f; 3、Runnable 和 Callable 的区别&#xff1f; 4、如何启动一个新线程、调用 start 和 run 方法的区别&#xff1f; 5、线程有哪几种状态以及各种状态之间的转换&#xff1f; 6、线程…

内网穿透的应用-如何在Android Termux上部署MySQL数据库并实现无公网IP远程访问

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…

(十一)RabbitMQ及SpringAMQP

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;…

YOLOV9 + 双目测距

YOLOV9 双目测距 1. 环境配置2. 测距流程和原理2.1 测距流程2.2 测距原理 3. 代码部分解析3.1 相机参数stereoconfig.py3.2 测距部分3.3 主代码yolov9-stereo.py 4. 实验结果4.1 测距4.2 视频展示 相关文章 1. YOLOV5 双目测距&#xff08;python&#xff09; 2. YOLOv7双目…

第十四届蓝桥杯C/C++大学B组题解(一)

1、日期统计 #include <bits/stdc.h> using namespace std; int main() {int array[100] {5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7,5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 6, 1, 8, 3, 0, 3, 7, 9,2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6,…

【第十九篇】使用BurpSuite实现XXE+点击劫持(实战案例)

XXE XXE漏洞的原理:攻击者通过注入特殊的XML实体来引用外部资源,比如本地文件系统中的文件。从而读取服务器上的敏感文件。 【1】Burp主动扫描 将条目发送至主动扫描: 仪表盘扫描出XML注入漏洞: 【2】手动测试 原请求包如下: 添加Payload并将 XML 中的数据值替换为我们…

多功能调解室sip可视对讲方案

多功能调解室sip可视对讲方案 人民调解委员会是依法设立的调解民间纠纷的群众性组织。 我国基层解决人民内部纠纷的群众性自治组织.人民调解委员会在城市以居民委员会为单位,农村以村民委员会为单位建立.其任务是: 及时发现纠纷,迅速解决争端.防止矛盾激化,预防,减少犯罪的发生…

EChart简单入门

echart的安装就细不讲了&#xff0c;直接去官网下&#xff0c;实在不会的直接用cdn,省的一番口舌。 cdn.staticfile.net/echarts/4.3.0/echarts.min.js 正入话题哈 什么是EChart&#xff1f; EChart 是一个使用 JavaScript 实现的开源可视化库&#xff0c;Echart支持多种常…

postgresql数据库|数据整合的好工具--Oracle-fdw的部署和使用

概述 Oracle_fdw 是一种postgresql外部表插件&#xff0c;可以读取到Oracle上面的数据。是一种非常方便且常见的pg与Oracle的同步数据的方法 Oracle_fdw 适用场景&#xff1a; Oracle_fdw 是一个开源的 Foreign Data Wrapper (FDW)&#xff0c;主要用于在 PostgreSQL 数据库中…

【2024】Rancher的安装与介绍

———————————————————————————— 记录一下rancher的学习与使用过程 本部分内容包括rancher的介绍、特点、与k8s关系和部署等内容 ———————————————————————————— Rancher是什么&#xff1f; 简单来说&#xff0c;Ranc…

Jackson 2.x 系列【13】特征配置篇之 DeserializationFeature

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. 值处理2.1 USE_BIG_DECIMAL_FOR_FLOATS2.2 USE_BIG_INTEGER_FOR_INTS2…

Qt QML的插件(Qt Quick 2 Extension Plugin)方法

Qt Quick的插件方法 序言环境前置注意概念——Qt Quick插件的相关知识模块名的相关知识模块名本身注意事项模块名版本注意事项 以示例来说明创建插件qmltypes的生成qmltypes的可能性失效 插件的编码注意1、插件模块版本控制2、pro里的注意 调用插件插件信息输入 序言 网上有很…

清明作业 c++

1.封装一个类&#xff0c;实现对一个数求累和阶乘质数 #include <iostream>using namespace std; int mproduct(int a){if(a>1){return a*mproduct((a-1));}else{return 1;} } class number{int a; public:number():a(5){};number(int a):a(a){}void set(int a){thi…

Linux Shell:`awk` 命令

Linux Shell&#xff1a;awk 命令 awk 是一种强大的文本分析工具&#xff0c;广泛用于文本处理、数据提取和报告生成。它使用自己的编程语言来处理文件中的数据。在 Linux Shell 中&#xff0c;awk 命令能够执行复杂的模式匹配、编辑和分析任务。本文将介绍 awk 的基础用法、高…

解锁网络安全新境界:雷池WAF社区版让网站防护变得轻而易举!

网站运营者的救星&#xff1a;雷池WAF社区版 ️ 嘿朋友们&#xff01;今天我超级激动要跟你们分享一个神器——雷池WAF社区版。这个宝贝对我们这帮网站运营者来说&#xff0c;简直就是保护伞&#xff01; 智能语义分析技术&#xff1a;超级侦探上线 先说说为啥我这么稀饭它。雷…

Python项目21:一个简单的记账系统(收入+支出+查询)

------------★Python练手项目源码★------------ Python项目源码20&#xff1a;银行管理系统&#xff08;开户、查询、取款、存款、转账、锁定、解锁、退出&#xff09; Python项目19&#xff1a;学员信息管理系统&#xff08;简易版&#xff09; Python项目18&#xff1a;…

PID控制有物理含义吗

PID控制有物理含义吗 一、背景 对于PID的初学者&#xff0c;经常会有疑惑&#xff0c;为什么位置的误差通过PID就变成了期望速度&#xff1f;他们之间有什么物理关系吗&#xff1f;还有对于无人机&#xff0c;为什么期望升力&#xff0c;又是期望加速度&#xff0c;又是期望油…

DFS(排列数字、飞机降落、选数、自然数的拆分)

注&#xff1a;1.首先要知道退出条件 2.还原现场 典型&#xff1a;全排列 题目1&#xff1a; 代码&#xff1a; #include<bits/stdc.h> using namespace std; int a[1005],p[1005],v[1005]; int n; void dfs(int x) {//此次dfs结束条件,即搜到底 if(xn1){for(int i1;i&…

多线程代码设计模式之单例模式

目录 设计模式引入 饿汉模式 懒汉模式 单例模式总结 设计模式引入 1.1.什么是设计模式 &#xff08;1&#xff09;设计模式就是一种代码的套用模板。例如&#xff1a;一类题型的步骤分别有哪些&#xff0c;是可以直接套用的。 &#xff08;2&#xff09;像棋谱&#xff…