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()改变绘图的开始位置。
二、效果图
三种渐变的方向和效果图:
三、详解
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、运行结果
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. }
运行结果:
注意:提高画图的效率!
二 画板小项目
头文件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. }
运行结果:
注意:
- 需要在鼠标移动的时候调用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. };
- #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. }
功能:新加了一个按钮
3 图片渐变的三种方式下三种模式
线性,弧形,辐射
简述
QGradient 可以和 QBrush 组合使用,来指定渐变填充。
Qt 目前支持三种类型的渐变填充:
- QLinearGradient:显示从起点到终点的渐变
- QRadialGradient:以圆心为中心显示渐变
- QConicalGradient:围绕一个中心点显示渐变
渐变类型可以使用 type() 函数来检索,类型中的每一个都是 QGradient 的子类。
- 简述
- 渐变类型
- QLinearGradient
- QRadialGradient
- QConicalGradient
渐变类型
QLinearGradient | QRadialGradient | QConicalGradient |
使用 QGradientStop 类来描述渐变中过渡点的位置和颜色。例如:一个位置和一个颜色。使用 setColorAt() 函数来定义一个过渡点。或者,使用 setStops() 函数来一次定义多个过渡点。需要注意的是,后者的功能将替换当前设置的过渡点。
这是渐变的一套完整的过渡点(通过 stops() 来访问)描述渐变区域如何被填充。如果没有指定任何过渡点,那么将会从 0 点(黑色)渐变为 1 点(白色)。
QLinearGradient
QLinearGradient 显示从起点到终点的渐变。
QGradient::PadSpread | QGradient::RepeatSpread | QGradient::ReflectSpread |
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 |
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) 为中心显示渐变。
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));
}