這個控件主要是模仿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(); }