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

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

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

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

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

代码如下:

cpp 复制代码
#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色)
cpp 复制代码
#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
cpp 复制代码
#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]);

}
cpp 复制代码
#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);
}
相关推荐
17´33 分钟前
Qt从入门到入土(八) -打包Qt程序
开发语言·c++·qt
AI+程序员在路上34 分钟前
QT显示网页控件QAxWidget、QWebEngineView及区别
开发语言·qt
坚定学代码4 小时前
Qt C++ 实际开发中宏编译的运用
c++·qt
恋恋风辰6 小时前
QT系列教程(17) MVC结构之Model模型介绍
开发语言·qt·mvc
水瓶丫头站住19 小时前
Qt的QGraphicsView控件的样式设置
qt·样式设置
已是上好佳20 小时前
介绍一下Qt 中的QSizePolicy 布局策略
数据库·qt
ccloud111 天前
OpenGL实现场景编辑器
qt·游戏引擎
熬夜的猪仔1 天前
QT多线程
qt
꧁坚持很酷꧂1 天前
QT登录系统界面
开发语言·qt
达斯维达的大眼睛2 天前
qt小项目,简单的音乐播放器
开发语言·qt