Qt提供了三种渐变画刷,分别是线性渐变(QLinearGradient)、辐射渐变(QRadialGradient)、角度渐变(QConicalGradient)。很多绘图系统都内置了渐变的功能,渐变的设置就是在QBrush里面。
       QT的QPainterPath类由一些图形如曲线、矩形、椭圆组成的对象,能保存已经绘制好的图形从而实现图形元素的构造和复用,图形状只需创建一次,然后调用QPainter::drawPath()函数多次绘制,painterpath可以加入闭合或不闭合的图形,QPainterPath可用于填充,描边,clipping。QPainterPath一旦创建,直线和曲线都可以被添加入path,通过lineTo()、arcTo()、cubicTo()和quadTo()函数,currentPosition()是最后一次绘制后的“结束点”(或初始点),使用moveTo()移动currentPosition()不会添加任何元素,moveTo() 隐含的开始一个新subpath,并且闭合前一个。 一个path 添加到另一个path用connectPath()。它默认是从原点(0,0)开始绘图,可以使用moveTo()改变绘图的开始位置。 

二、效果图


三种渐变的方向和效果图:

android paint 怎么设置渐变 painter怎么渐变_#define



三、详解

1、代码


(1)widget.h


[html]  view plain  copy



1. #ifndef WIDGET_H  
2. #define WIDGET_H  
3.   
4. #include <QWidget>  
5. #include <QPainter>  
6.   
7. class Widget : public QWidget  
8. {  
9.     Q_OBJECT  
10.   
11. public:  
12. parent = 0);  
13.     ~Widget();  
14.   
15. protected:  
16.     void paintEvent(QPaintEvent *event);  
17. };  
18.   
19. #endif // WIDGET_H

(2)widget.cpp


[html]  view plain  copy



1. #include "widget.h"  
2.   
3. Widget::Widget(QWidget *parent)  
4.     : QWidget(parent)  
5. {  
6.     resize(400, 400);  
7. }  
8.   
9. Widget::~Widget()  
10. {  
11.   
12. }  
13.   
14. void Widget::paintEvent(QPaintEvent *event)  
15. {  
16.     QPainter painter(this);  
17.     painter.setRenderHint(QPainter::Antialiasing);  
18.     painter.setRenderHint(QPainter::SmoothPixmapTransform);  
19.     painter.save();  
20.     //线性渐变,渐变开始,和结束点  
21.     QLinearGradient linearGradient(10,10,100,100);  
22.     //创建了一个QLinearGradient对象实例,参数为起点和终点坐标,可作为颜色渐变的方向  
23.     //painter.setPen(Qt::NoPen);  
24.     linearGradient.setColorAt(0.0,Qt::green);  
25.     linearGradient.setColorAt(0.2,Qt::white);  
26.     linearGradient.setColorAt(0.4,Qt::blue);  
27.     linearGradient.setColorAt(0.6,Qt::red);  
28.     linearGradient.setColorAt(1.0,Qt::yellow);  
29.     painter.setBrush(QBrush(linearGradient));  
30.     painter.drawEllipse(10,10,100,100);  
31.     //前面为左边,后面两个参数为横轴和纵轴,上面的四行分别设置渐变的颜色和路径比例  
32.   
33.     //辐射渐变  
34.     QRadialGradient radialGradient(10+50 , 120+50, 50, 60, 170);  
35.     //创建了一个QRadialGradient对象实例,参数分别为中心坐标,半径长度和焦点坐标,如果需要对称那么中心坐标和焦点坐标要一致  
36.     radialGradient.setColorAt(0,Qt::green);  
37.     radialGradient.setColorAt(0.2,Qt::white);  
38.     radialGradient.setColorAt(0.4,Qt::blue);  
39.     radialGradient.setColorAt(0.6,Qt::red);  
40.     radialGradient.setColorAt(1.0,Qt::yellow);  
41.     painter.setBrush(QBrush(radialGradient));  
42.     painter.drawEllipse(10,120,100,100);//在相应的坐标画出来  
43.   
44.     //弧度渐变  
45.     QConicalGradient conicalGradient(10+50,  230 + 50,0);  
46.     //创建了一个QConicalGradient对象实例,参数分别为中心坐标和初始角度  
47.     conicalGradient.setColorAt(0,Qt::green);  
48.     conicalGradient.setColorAt(0.2,Qt::white);  
49.     conicalGradient.setColorAt(0.4,Qt::blue);  
50.     conicalGradient.setColorAt(0.6,Qt::red);  
51.     conicalGradient.setColorAt(0.8,Qt::yellow);  
52.     conicalGradient.setColorAt(1.0,Qt::green);  
53.     //设置渐变的颜色和路径比例  
54.     painter.setBrush(QBrush(conicalGradient));  
55.     painter.drawEllipse(10, 230, 100, 100);//在相应的坐标画出来  
56.     painter.restore();  
57.   
58.     painter.save();  
59.     QConicalGradient conicalGradient2(width()/2, height()/2, 90);  
60.     conicalGradient2.setColorAt(0, QColor(45, 204, 112));  
61.     conicalGradient2.setColorAt(1.0, QColor(51, 152, 219));  
62.     painter.setPen(QPen(QBrush(conicalGradient2), 30));  
63.     painter.drawEllipse(QRectF((width()/2 - 65), (height()/2 - 65), 130, 130));  
64.     painter.restore();  
65.   
66.     //QPainterPath画圆角矩形  
67.     painter.save();  
68. radius = 26;  
69.     QPainterPath path;  
70. rect = QRect(150, 10, 100, 100);  
71.     QLinearGradient myGradient(rect.topLeft(), rect.bottomRight());  
72.     myGradient.setColorAt(0.0,Qt::green);  
73.     myGradient.setColorAt(0.9,Qt::yellow);  
74.     path.moveTo(rect.topRight() - QPointF(radius, 0));  
75.     path.lineTo(rect.topLeft() + QPointF(radius, 0));  
76.     path.quadTo(rect.topLeft(), rect.topLeft() + QPointF(0, radius));  
77.     path.lineTo(rect.bottomLeft() + QPointF(0, -radius));  
78.     path.quadTo(rect.bottomLeft(), rect.bottomLeft() + QPointF(radius, 0));  
79.     path.lineTo(rect.bottomRight() - QPointF(radius, 0));  
80.     path.quadTo(rect.bottomRight(), rect.bottomRight() + QPointF(0, -radius));  
81.     path.lineTo(rect.topRight() + QPointF(0, radius));  
82.     path.quadTo(rect.topRight(), rect.topRight() + QPointF(-radius, -0));  
83.     painter.setBrush(myGradient);  
84.     painter.fillPath(path, QColor(Qt::green));  
85.     painter.drawPath(path);  
86.     painter.restore();  
87.     QWidget::paintEvent(event);  
88. }

(3)main.cpp


[html]  view plain  copy




1. #include "widget.h"  
2. #include <QApplication>  
3.   
4. int main(int argc, char *argv[])  
5. {  
6.     QApplication a(argc, argv);  
7.     Widget w;  
8.     w.show();  
9.   
10.     return a.exec();  
11. }


2、运行结果

android paint 怎么设置渐变 painter怎么渐变_#define_02


2 绘图中,和插入图片qpixmap


    1. #include "mywidget.h"  
    2. #include<QApplication>  
    3. #include<QPixmap>  
    4.   
    5. Mywidget::Mywidget(QWidget *parent) : QWidget(parent)  
    6. {  
    7.   
    8. }  
    9.   
    10. void Mywidget::paintEvent(QPaintEvent *e)  
    11. {  
    12. //相当于小汽车,将所画的东西打包塞进小汽车中  
    13.   
    14. //paintEvent需要画笔工具QPainter,在头文件QPainter中  
    15. //画在小汽车里边,能有效提高效率  
    16.   
    17.   
    18.     QTransform transform;  
    19. //transform可以代替p的translate,因为他会进行一系列复杂的运算,平移、旋转、缩放等等  
    20. //虽然p也有scale,rotate,translate等函数  
    21.     transform.rotate(10);  
    22. //缩放功能  
    23. //将以下所有的图像旋转10度,改语句后面的所画的图像都要旋转  
    24.     p.setTransform(transform);  
    25. //将下方画的所有图形移动相对应的位置,整体图像平移,只影响这句话之后的语句,知道遇到下一个translate语句  
    26.     p.translate(100, 100);  
    27. //消锯齿,让画出的图形更加美观  
    28.     p.setRenderHint(QPainter::SmoothPixmapTransform);  
    29. //设置画笔属性  
    30.     p.setPen(QPen(Qt::red, 2, Qt::DashDotLine));  
    31. //设置封闭图像的填充颜色,从BrushStyle文件中找,要学会查询函数的使用准则  
    32.     p.setBrush(Qt::CrossPattern);  
    33. //设置字体格式,宋体, 40个像素, 加粗值为100, 斜体  
    34. "宋体", 40, 100, true));  
    35.   
    36.     QTransform transform2;  
    37.     transform.scale(0.5, 0.5);  
    38. //这里的false代表是和前面的transform相互独立,效果不叠加  
    39. false);  
    40.   
    41.   
    42. //画一条直线  
    43.     p.drawLine(QPoint(0, 0), QPoint(100, 100));  
    44. //画一个椭圆,第一个参数为中心点,第二个第三个分别为x和y的轴长,当二者相等时未圆  
    45.     p.drawEllipse(QPoint(100, 100), 50, 50);  
    46. //画字  
    47. "Hello, China!");  
    48. //画图  
    49. "pic.jpg"));  
    50. //画出直角矩形  
    51.     p.drawRect(QRect(150, 150, 100,60));  
    52. //画出有弧的矩形  
    53.     p.drawRoundedRect(QRect(230, 230, 100,60), 20, 20);  
    54.   
    55. //结束画笔  
    56.     p.end();  
    57.   
    58. //开始在窗口上画,画什么呢?  
    59. this);  
    60. //前方开始装车的过程,最后一股气打包全部带走,送到窗口  
    61. //北京颜色发生了改变,怎么变回来呢?  
    62.     p.drawPixmap(QPoint(0, 0), pixmap);  
    63. }  
    64.   
    65. int main(int argc, char *argv[])  
    66. {  
    67.     QApplication app(argc, argv);  
    68.   
    69.     Mywidget w;  
    70.     w.show();  
    71.   
    72.     app.exec();  
    73. }



    运行结果:


    android paint 怎么设置渐变 painter怎么渐变_#define_03

    注意:提高画图的效率!

    二 画板小项目



    头文件Mywidget.h



    [cpp]  view plain  copy




      1. #ifndef MYWIDGET_H  
      2. #define MYWIDGET_H  
      3.   
      4. #include<QWidget>  
      5. #include<QPainter>  
      6. #include<QMouseEvent>  
      7.   
      8. class Mywidget : public QWidget  
      9. {  
      10.     Q_OBJECT  
      11. public:  
      12. explicit Mywidget(QWidget *parent = 0);  
      13.   
      14. void paintEvent(QPaintEvent *ev);  
      15. void mouseMoveEvent(QMouseEvent *ev);  
      16. void mousePressEvent(QMouseEvent *ev);  
      17. void mouseReleaseEvent(QMouseEvent *ev);  
      18.   
      19. //画多条线  
      20. signals:  
      21.   
      22. public slots:  
      23. };  
      24.   
      25. #endif // MYWIDGET_H



      源文件:



      [cpp]  view plain  copy



      1. #include "mywidget.h"  
      2. #include<QApplication>  
      3.   
      4. Mywidget::Mywidget(QWidget *parent) : QWidget(parent)  
      5. {  
      6.   
      7. }  
      8.   
      9. void Mywidget::paintEvent(QPaintEvent *)  
      10. {  
      11. this);  
      12. for(int i=0; i<_lines.size(); i++)  
      13.     {  
      14. const QVector<QPoint> &line = _lines.at(i);  
      15. for(int j=0; j<line.size()-1; j++)  
      16.             p.drawLine(line.at(j), line.at(j+1));  
      17.     }  
      18. }  
      19.   
      20. void Mywidget::mouseMoveEvent(QMouseEvent *ev)  
      21. {  
      22. if(_lines.size() == 0)  
      23.     {  
      24.         QVector<QPoint> line;  
      25.         _lines.append(line);  
      26.     }  
      27.   
      28.     QVector<QPoint> &lastLine = _lines.last();  
      29. //记录该条线当前的位置  
      30.     lastLine.append(ev->pos());  
      31. //强制重绘  
      32.     update();  
      33. }  
      34.   
      35. void Mywidget::mousePressEvent(QMouseEvent *ev)  
      36. {  
      37. //每次点击鼠标都会为之绘画一条新的线,并将该线的起点位置添加到_lines中  
      38.     QVector<QPoint> line;  
      39.     _lines.append(line);  
      40.   
      41. //记录下该条线当前的位置  
      42.     QVector<QPoint> &lastLine = _lines.last();  
      43.     lastLine.append(ev->pos());  
      44. }  
      45.   
      46. void Mywidget::mouseReleaseEvent(QMouseEvent *ev)  
      47. {  
      48.     QVector<QPoint> &lastLine = _lines.last();  
      49.     lastLine.append(ev->pos());  
      50. }  
      51.   
      52. int main(int argc, char *argv[])  
      53. {  
      54.     QApplication app(argc, argv);  
      55.   
      56.     Mywidget w;  
      57.     w.show();  
      58.   
      59. return app.exec();  
      60. }


      运行结果:




      android paint 怎么设置渐变 painter怎么渐变_Qt_04




      注意:


      • 需要在鼠标移动的时候调用update(),使之强制重绘,否则,画面版上不会出现任何效果。
      • QVector函数的使用方法和CPP中的Vector方法差不多。


      三 在该项目的基础上增加一个按钮



      新增一个类MyButton.h



      [cpp]  view plain  copy


      1. #ifndef MYBUTTON_H  
      2. #define MYBUTTON_H  
      3.   
      4. #include <QWidget>  
      5.   
      6. class MyButton : public QWidget  
      7. {  
      8.     Q_OBJECT  
      9. public:  
      10. explicit MyButton(QWidget *parent = 0);  
      11. const QString& text, QWidget* parent = 0);  
      12.   
      13.     QRect _rect;  
      14.     QString _text;  
      15. bool _pressed;  
      16. void mousePressEvent(QMouseEvent *);  
      17. void mouseReleaseEvent(QMouseEvent *);  
      18.   
      19. void paintEvent(QPaintEvent *);  
      20.   
      21. signals:  
      22. void clicked();  
      23.   
      24. public slots:  
      25.   
      26. };
      1.   
      2. #endif // MYBUTTON_H  


      源文件MyButton.cpp



      [cpp]  view plain  copy


        1. #include "MyButton.h"  
        2. #include <QPainter>  
        3. #include <QMouseEvent>  
        4. MyButton::MyButton(QWidget *parent) :  
        5.     QWidget(parent), _rect(0, 0, 100, 30), _text(QString())  
        6. {  
        7. false;  
        8. this->setGeometry(_rect);  
        9. }  
        10.   
        11. MyButton::MyButton(const QString &text, QWidget *parent):  
        12.     QWidget(parent), _text(text), _rect(0, 0, 100, 30)  
        13. {  
        14. false;  
        15. this->setGeometry(_rect);  
        16. }  
        17.   
        18. void MyButton::mousePressEvent(QMouseEvent *)  
        19. {  
        20. true;  
        21.     update();  
        22. }  
        23.   
        24. void MyButton::mouseReleaseEvent(QMouseEvent *ev)  
        25. {  
        26. false;  
        27.     update();  
        28.   
        29. if(_rect.contains(ev->pos()))  
        30.         emit clicked();  
        31. // callback handler  
        32. }  
        33. void MyButton::paintEvent(QPaintEvent *)  
        34. {  
        35. this);  
        36. if(_pressed)  
        37.         p.setBrush(Qt::yellow);  
        38. else  
        39.         p.setBrush(Qt::darkGray);  
        40.     p.drawRect(_rect);  
        41.     p.drawText(_rect, _text, QTextOption(Qt::AlignCenter));  
        42. }




        [cpp]  view plain  copy

        1. #ifndef MYWIDGET_H  
        2. #define MYWIDGET_H  
        3.   
        4. #include <QWidget>  
        5. #include "MyButton.h"  
        6.   
        7. class MyWidget : public QWidget  
        8. {  
        9.     Q_OBJECT  
        10. public:  
        11. explicit MyWidget(QWidget *parent = 0);  
        12.   
        13.     MyButton* button;  
        14.   
        15. void paintEvent(QPaintEvent *);  
        16.   
        17. void mousePressEvent(QMouseEvent *);  
        18. void mouseReleaseEvent(QMouseEvent *);  
        19. void mouseMoveEvent(QMouseEvent *);  
        20.   
        21.     QVector< QVector<QPoint> > _lines;  
        22.   
        23. signals:  
        24.   
        25. public slots:  
        26. void slotButtonClicked();  
        27. };  
        28.   
        29. #endif // MYWIDGET_H

        MyWidget.cpp



        [cpp]  view plain  copy

        1. #include "MyWidget.h"  
        2. #include <QPainter>  
        3. #include <QPixmap>  
        4. #include <QMouseEvent>  
        5. #include <QDebug>  
        6.   
        7. MyWidget::MyWidget(QWidget *parent) :  
        8.     QWidget(parent)  
        9. {  
        10. new MyButton("MyButton", this);  
        11. this, SLOT(slotButtonClicked()));  
        12.   
        13. //    button->setGeometry(30, 30, 100, 30);  
        14. }  
        15.   
        16. void MyWidget::slotButtonClicked()  
        17. {  
        18. "button is clicked";  
        19. }  
        20.   
        21. void MyWidget::paintEvent(QPaintEvent *)  
        22. {  
        23. this);  
        24. for(int i=0; i<_lines.size(); ++i)  
        25.     {  
        26. const QVector<QPoint>& line = _lines.at(i);  
        27. for(int j=0; j<line.size()-1; ++j)  
        28.         {  
        29.             p.drawLine(line.at(j), line.at(j+1));  
        30.         }  
        31.     }  
        32. }  
        33.   
        34. void MyWidget::mouseMoveEvent(QMouseEvent *ev)  
        35. {  
        36. if(_lines.size() == 0)  
        37.     {  
        38.         QVector<QPoint> line;  
        39.         _lines.append(line);  
        40.     }  
        41.   
        42.     QVector<QPoint>& lastLine = _lines.last();  
        43.     lastLine.append(ev->pos());  
        44.   
        45.     update();  
        46. }  
        47. void MyWidget::mousePressEvent(QMouseEvent *ev)  
        48. {  
        49.     QVector<QPoint> line;  
        50.     _lines.append(line);  
        51.   
        52.     QVector<QPoint>& lastLine = _lines.last();  
        53.     lastLine.append(ev->pos());  
        54. }  
        55. void MyWidget::mouseReleaseEvent(QMouseEvent *ev)  
        56. {  
        57.     QVector<QPoint>& lastLine = _lines.last();  
        58.     lastLine.append(ev->pos());  
        59. }  
        60.   
        61. #include <QApplication>  
        62. int main(int argc, char** argv)  
        63. {  
        64.     QApplication app(argc, argv);  
        65.   
        66.     MyWidget w;  
        67.     w.show();  
        68.   
        69. return app.exec();  
        70. }


        功能:新加了一个按钮

        android paint 怎么设置渐变 painter怎么渐变_#define_05

        3 图片渐变的三种方式下三种模式

        线性,弧形,辐射

        简述

        QGradient 可以和 QBrush 组合使用,来指定渐变填充。

        Qt 目前支持三种类型的渐变填充:

        • QLinearGradient:显示从起点到终点的渐变
        • QRadialGradient:以圆心为中心显示渐变
        • QConicalGradient:围绕一个中心点显示渐变

        渐变类型可以使用 type() 函数来检索,类型中的每一个都是 QGradient 的子类。


        • 简述
        • 渐变类型
        • QLinearGradient
        • QRadialGradient
        • QConicalGradient

        渐变类型

        QLinearGradient

        QRadialGradient

        QConicalGradient


        android paint 怎么设置渐变 painter怎么渐变_#define_06


        android paint 怎么设置渐变 painter怎么渐变_#define_07


        android paint 怎么设置渐变 painter怎么渐变_#define_08

        使用 QGradientStop 类来描述渐变中过渡点的位置和颜色。例如:一个位置和一个颜色。使用 setColorAt() 函数来定义一个过渡点。或者,使用 setStops() 函数来一次定义多个过渡点。需要注意的是,后者的功能将替换当前设置的过渡点。

        这是渐变的一套完整的过渡点(通过 stops() 来访问)描述渐变区域如何被填充。如果没有指定任何过渡点,那么将会从 0 点(黑色)渐变为 1 点(白色)。

        QLinearGradient

        QLinearGradient 显示从起点到终点的渐变。

        QGradient::PadSpread

        QGradient::RepeatSpread

        QGradient::ReflectSpread


        android paint 怎么设置渐变 painter怎么渐变_#define_09


        android paint 怎么设置渐变 painter怎么渐变_#include_10


        android paint 怎么设置渐变 painter怎么渐变_#define_11

        void MainWindow::paintEvent(QPaintEvent *event)
        {
            Q_UNUSED(event);
        
            QPainter painter(this);
        
            // 反走样
            painter.setRenderHint(QPainter::Antialiasing, true);
        
            // 设置渐变色
            QLinearGradient linear(QPointF(80, 80), QPointF(150, 150));
            linear.setColorAt(0, Qt::black);
            linear.setColorAt(1, Qt::white);
        
            // 设置显示模式
            linear.setSpread(QGradient::PadSpread);
        
            // 设置画笔颜色、宽度
            painter.setPen(QPen(QColor(0, 160, 230), 2));
        
            // 设置画刷填充
            painter.setBrush(linear);
        
            // 绘制椭圆
            painter.drawRect(QRect(40, 40, 180, 180));
        }

        QLinearGradient 构造函数的第一个参数指定起点,第二个参数指定终点,然后显示渐变。函数setColorAt() 用于设置起点和终点之间要显示的颜色,setSpread() 可以设置起点和终点区域之外的显示模式。

        QRadialGradient

        QRadialGradient 类以圆心为中心显示渐变。(cx, cy) 是中点,半径(radius)是以中点为圆心的圆的半径,(fx, fy) 是渐变的起点。

        QGradient::PadSpread

        QGradient::RepeatSpread

        QGradient::ReflectSpread


        android paint 怎么设置渐变 painter怎么渐变_#define_12


        android paint 怎么设置渐变 painter怎么渐变_Qt_13


        android paint 怎么设置渐变 painter怎么渐变_#include_14

        void MainWindow::paintEvent(QPaintEvent *event)
        {
            Q_UNUSED(event);
        
            QPainter painter(this);
        
            // 反走样
            painter.setRenderHint(QPainter::Antialiasing, true);
        
            // 设置渐变色
            QRadialGradient radial(110, 110, 50, 130, 130);
            radial.setColorAt(0, Qt::black);
            radial.setColorAt(1, Qt::white);
        
            // 设置显示模式
            radial.setSpread(QGradient::ReflectSpread );
        
            // 设置画笔颜色、宽度
            painter.setPen(QPen(QColor(0, 160, 230), 2));
        
            // 设置画刷填充
            painter.setBrush(radial);
        
            // 绘制椭圆
            painter.drawRect(QRect(40, 40, 180, 180));
        }

        QRadialGradient 构造函数的第一个参数和第二个参数是 (cx, cy) 坐标,第三个参数是半径,第四个和第五个参数是 (fx, fy) 坐标。

        QConicalGradient

        QConicalGradient 在 (cx, cy) 坐标上以角度 (angle) 为中心显示渐变。


        android paint 怎么设置渐变 painter怎么渐变_#define_15

        void MainWindow::paintEvent(QPaintEvent *event)
        {
            Q_UNUSED(event);
        
            QPainter painter(this);
        
            // 反走样
            painter.setRenderHint(QPainter::Antialiasing, true);
        
            // 设置渐变色
            QConicalGradient conical(110, 110, 45);
            conical.setColorAt(0, Qt::black);
            conical.setColorAt(1, Qt::white);
        
            // 设置画笔颜色、宽度
            painter.setPen(QPen(QColor(0, 160, 230), 2));
        
            // 设置画刷填充
            painter.setBrush(conical);
        
            // 绘制椭圆
            painter.drawRect(QRect(40, 40, 180, 180));
        }