这个控件主要是模仿QColorDialog对话框中的颜色选取面板,提供一个十字形状的标识器,鼠标按下开始选取颜色,移动到哪就选择该处的颜色值,对应右侧颜色条放大显示,本控件的难点就是如何绘制一个边缘框限定鼠标只能在此框中移动,还有一个就是如何绘制颜色渐变的背景颜色集合,这里采用的是对每个像素的高度区域设置不一样的开始颜色+中间颜色+结束颜色,做为渐变颜色,而后设置QLinearGradient做为画笔的颜色进行绘制,其实就是假设宽度是100,实际上是绘制了100条垂直方向的竖线而造成的效果。在绘制画布的时候,能够将其绘制到一个pixmap上,这样也方便待会鼠标移动时候直接取该pixmap的某个像素点的颜色值。linux
#ifndef COLORPANELHSB_H #define COLORPANELHSB_H /** * 颜色选取面板 做者:feiyangqingyun(QQ:517216493) 2017-11-17 * 1:可设置当前百分比,用于控制指针大小 * 2:可设置边框宽度 * 3:可设置边框颜色 * 4:可设置指针颜色 */ #include <QWidget> #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT ColorPanelHSB : public QWidget #else class ColorPanelHSB : public QWidget #endif { Q_OBJECT Q_PROPERTY(int percent READ getPercent WRITE setPercent) Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor) Q_PROPERTY(QColor cursorColor READ getCursorColor WRITE setCursorColor) Q_PROPERTY(QColor color READ getColor) Q_PROPERTY(double hue READ getHue) Q_PROPERTY(double sat READ getSat) public: explicit ColorPanelHSB(QWidget *parent = 0); protected: void showEvent(QShowEvent *); void resizeEvent(QResizeEvent *); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void paintEvent(QPaintEvent *); void drawBg(QPainter *painter); void drawCursor(QPainter *painter); void drawBorder(QPainter *painter); private: int percent; //当前百分比 int borderWidth; //边框宽度 QColor borderColor; //边框颜色 QColor cursorColor; //鼠标按下处的文字形状颜色 QColor color; //鼠标按下处的颜色 double hue; //hue值 double sat; //sat值 QPoint lastPos; //最后鼠标按下去的坐标 QPixmap bgPix; //背景颜色图片 public: int getPercent() const; QColor getBorderColor() const; QColor getCursorColor() const; QColor getColor() const; double getHue() const; double getSat() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //设置百分比 void setPercent(int percent); //设置边框颜色 void setBorderColor(const QColor &borderColor); //设置文字形状颜色 void setCursorColor(const QColor &cursorColor); Q_SIGNALS: void colorChanged(const QColor &color, double hue, double sat); }; #endif // COLORPANELHSB_H
void ColorPanelHSB::paintEvent(QPaintEvent *) { //绘制准备工做,启用反锯齿 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //绘制背景颜色 drawBg(&painter); //绘制按下出的形状 drawCursor(&painter); //绘制边框 drawBorder(&painter); } void ColorPanelHSB::drawBg(QPainter *painter) { painter->save(); if (!bgPix.isNull()) { painter->drawPixmap(0, 0, bgPix); } painter->restore(); } void ColorPanelHSB::drawCursor(QPainter *painter) { painter->save(); painter->setPen(cursorColor); QString text = "+"; //根据右侧的百分比显示字体大小 QFont textFont; int size = 20 + (35 * (double)percent / 100); textFont.setPixelSize(size); //计算文字的宽度高度,自动移到鼠标按下处的中心点 QFontMetrics fm(textFont); int textWidth = fm.width(text); int textHeight = fm.height(); QPoint textPoint = lastPos - QPoint(textWidth / 2, -(textHeight / 4)); QPainterPath path; path.addText(textPoint, textFont, text); painter->drawPath(path); painter->restore(); } void ColorPanelHSB::drawBorder(QPainter *painter) { painter->save(); int width = this->width(); int height = this->height(); int offset = borderWidth; QPen pen; pen.setWidth(offset); pen.setColor(borderColor); pen.setCapStyle(Qt::RoundCap); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); painter->setBrush(Qt::NoBrush); painter->drawRect(offset / 2, offset / 2, width - offset, height - offset); painter->restore(); }