效果:
代码:
#ifndef COLORSELECTIONRINGWIDGET_H
#define COLORSELECTIONRINGWIDGET_H
#include <QWidget>
class ColorSelectionRingWidget : public QWidget
{
Q_OBJECT
public:
ColorSelectionRingWidget(QWidget *parent = nullptr);
~ColorSelectionRingWidget()override;
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;
private:
qreal ballAngle{0};
bool isPressed{false};
void getColorInWidget(const QPoint & pos);
QColor selectColor;//当前颜色
};
#endif // COLORSELECTIONRINGWIDGET_H
#include "colorselectionringwidget.h"
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <QDebug>
#include <QtMath>
#include <QGuiApplication>
#include <QScreen>
ColorSelectionRingWidget::ColorSelectionRingWidget(QWidget *parent)
: QWidget(parent)
{
setPalette(Qt::white);
setMinimumSize(150,150);
}
ColorSelectionRingWidget::~ColorSelectionRingWidget()
{
}
void ColorSelectionRingWidget::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); //两点之间的角度(弧度)
qDebug()<<"角度 "<<ballAngle;
isPressed = true;
update();
}
QWidget::mousePressEvent(event);
}
void ColorSelectionRingWidget::mouseReleaseEvent(QMouseEvent* event)
{
if(isPressed)
{
isPressed = false;
}
return QWidget::mouseReleaseEvent(event);
}
void ColorSelectionRingWidget::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); //两点之间的角度(弧度)
update();
}
return QWidget::mouseMoveEvent(event);
}
void ColorSelectionRingWidget::showEvent(QShowEvent *event)
{
update();
return QWidget::showEvent(event);
}
void ColorSelectionRingWidget::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 ColorSelectionRingWidget::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); //创建渐变 前两个参数是渐变的中心点 第三个参数是渐变的角度
QList<Qt::GlobalColor> list{Qt::red,
Qt::yellow,
Qt::green,
Qt::cyan,
Qt::blue,
Qt::magenta};
for(int i = 0;i < list.size();++i)
{
conicalGradient.setColorAt(60.0 * i/360.0, list[i]);
}
conicalGradient.setColorAt(1.0, list[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;
path1.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("#128bf1"));
painter.drawEllipse(ballPos, radius*0.2, radius*0.2);
getColorInWidget(ballPos.toPoint() + QPoint(rect.width()/2,rect.height()/2));
painter.setBrush(selectColor);
painter.setPen(Qt::transparent);
painter.drawEllipse(QPoint(0, 0), radius * 0.6, radius * 0.6);
}