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
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QPainter>
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
-
- protected:
- void paintEvent(QPaintEvent *event);
- };
-
- #endif // WIDGET_H
(2)widget.cpp
- #include "widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- resize(400, 400);
- }
-
- Widget::~Widget()
- {
-
- }
-
- void Widget::paintEvent(QPaintEvent *event)
- {
- QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing);
- painter.setRenderHint(QPainter::SmoothPixmapTransform);
- painter.save();
- //线性渐变,渐变开始,和结束点
- QLinearGradient linearGradient(10,10,100,100);
- //创建了一个QLinearGradient对象实例,参数为起点和终点坐标,可作为颜色渐变的方向
- //painter.setPen(Qt::NoPen);
- linearGradient.setColorAt(0.0,Qt::green);
- linearGradient.setColorAt(0.2,Qt::white);
- linearGradient.setColorAt(0.4,Qt::blue);
- linearGradient.setColorAt(0.6,Qt::red);
- linearGradient.setColorAt(1.0,Qt::yellow);
- painter.setBrush(QBrush(linearGradient));
- painter.drawEllipse(10,10,100,100);
- //前面为左边,后面两个参数为横轴和纵轴,上面的四行分别设置渐变的颜色和路径比例
-
- //辐射渐变
- QRadialGradient radialGradient(10+50 , 120+50, 50, 60, 170);
- //创建了一个QRadialGradient对象实例,参数分别为中心坐标,半径长度和焦点坐标,如果需要对称那么中心坐标和焦点坐标要一致
- radialGradient.setColorAt(0,Qt::green);
- radialGradient.setColorAt(0.2,Qt::white);
- radialGradient.setColorAt(0.4,Qt::blue);
- radialGradient.setColorAt(0.6,Qt::red);
- radialGradient.setColorAt(1.0,Qt::yellow);
- painter.setBrush(QBrush(radialGradient));
- painter.drawEllipse(10,120,100,100);//在相应的坐标画出来
-
- //弧度渐变
- QConicalGradient conicalGradient(10+50, 230 + 50,0);
- //创建了一个QConicalGradient对象实例,参数分别为中心坐标和初始角度
- conicalGradient.setColorAt(0,Qt::green);
- conicalGradient.setColorAt(0.2,Qt::white);
- conicalGradient.setColorAt(0.4,Qt::blue);
- conicalGradient.setColorAt(0.6,Qt::red);
- conicalGradient.setColorAt(0.8,Qt::yellow);
- conicalGradient.setColorAt(1.0,Qt::green);
- //设置渐变的颜色和路径比例
- painter.setBrush(QBrush(conicalGradient));
- painter.drawEllipse(10, 230, 100, 100);//在相应的坐标画出来
- painter.restore();
-
- painter.save();
- QConicalGradient conicalGradient2(width()/2, height()/2, 90);
- conicalGradient2.setColorAt(0, QColor(45, 204, 112));
- conicalGradient2.setColorAt(1.0, QColor(51, 152, 219));
- painter.setPen(QPen(QBrush(conicalGradient2), 30));
- painter.drawEllipse(QRectF((width()/2 - 65), (height()/2 - 65), 130, 130));
- painter.restore();
-
- //QPainterPath画圆角矩形
- painter.save();
- const qreal radius = 26;
- QPainterPath path;
- QRectF rect = QRect(150, 10, 100, 100);
- QLinearGradient myGradient(rect.topLeft(), rect.bottomRight());
- myGradient.setColorAt(0.0,Qt::green);
- myGradient.setColorAt(0.9,Qt::yellow);
- path.moveTo(rect.topRight() - QPointF(radius, 0));
- path.lineTo(rect.topLeft() + QPointF(radius, 0));
- path.quadTo(rect.topLeft(), rect.topLeft() + QPointF(0, radius));
- path.lineTo(rect.bottomLeft() + QPointF(0, -radius));
- path.quadTo(rect.bottomLeft(), rect.bottomLeft() + QPointF(radius, 0));
- path.lineTo(rect.bottomRight() - QPointF(radius, 0));
- path.quadTo(rect.bottomRight(), rect.bottomRight() + QPointF(0, -radius));
- path.lineTo(rect.topRight() + QPointF(0, radius));
- path.quadTo(rect.topRight(), rect.topRight() + QPointF(-radius, -0));
- painter.setBrush(myGradient);
- painter.fillPath(path, QColor(Qt::green));
- painter.drawPath(path);
- painter.restore();
- QWidget::paintEvent(event);
- }
(3)main.cpp
- #include "widget.h"
- #include <QApplication>
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- Widget w;
- w.show();
-
- return a.exec();
- }
2、运行结果
2 绘图中,和插入图片qpixmap
- #include "mywidget.h"
- #include
- #include
-
- Mywidget::Mywidget(QWidget *parent) : QWidget(parent)
- {
-
- }
-
- void Mywidget::paintEvent(QPaintEvent *e)
- {
- QPixmap pixmap(size());
-
-
- QPainter p(&pixmap);
-
-
- QTransform transform;
-
-
- transform.rotate(10);
- transform.scale(0.8, 0.8);
-
- p.setTransform(transform);
-
- p.translate(100, 100);
-
- p.setRenderHint(QPainter::SmoothPixmapTransform);
-
- p.setPen(QPen(Qt::red, 2, Qt::DashDotLine));
-
- p.setBrush(Qt::CrossPattern);
-
- p.setFont(QFont("宋体", 40, 100, true));
-
- QTransform transform2;
- transform.scale(0.5, 0.5);
-
- p.setTransform(transform2, false);
-
-
-
- p.drawLine(QPoint(0, 0), QPoint(100, 100));
-
- p.drawEllipse(QPoint(100, 100), 50, 50);
-
- p.drawText(QPoint(200, 100), "Hello, China!");
-
- p.drawPixmap(QPoint(230, 300), QPixmap("pic.jpg"));
-
- p.drawRect(QRect(150, 150, 100,60));
-
- p.drawRoundedRect(QRect(230, 230, 100,60), 20, 20);
-
-
- p.end();
-
-
- p.begin(this);
-
-
- p.drawPixmap(QPoint(0, 0), pixmap);
- }
-
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
-
- Mywidget w;
- w.show();
-
- app.exec();
- }
运行结果:
注意:提高画图的效率!
二 画板小项目
头文件Mywidget.h
- #ifndef MYWIDGET_H
- #define MYWIDGET_H
-
- #include
- #include
- #include
-
- class Mywidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit Mywidget(QWidget *parent = 0);
-
- void paintEvent(QPaintEvent *ev);
- void mouseMoveEvent(QMouseEvent *ev);
- void mousePressEvent(QMouseEvent *ev);
- void mouseReleaseEvent(QMouseEvent *ev);
-
- QVector> _lines;
- signals:
-
- public slots:
- };
-
- #endif // MYWIDGET_H
源文件:
- #include "mywidget.h"
- #include
-
- Mywidget::Mywidget(QWidget *parent) : QWidget(parent)
- {
-
- }
-
- void Mywidget::paintEvent(QPaintEvent *)
- {
- QPainter p(this);
- for(int i=0; i<_lines.size(); i++)
- {
- const QVector &line = _lines.at(i);
- for(int j=0; j
- p.drawLine(line.at(j), line.at(j+1));
- }
- }
-
- void Mywidget::mouseMoveEvent(QMouseEvent *ev)
- {
- if(_lines.size() == 0)
- {
- QVector line;
- _lines.append(line);
- }
-
- QVector &lastLine = _lines.last();
-
- lastLine.append(ev->pos());
-
- update();
- }
-
- void Mywidget::mousePressEvent(QMouseEvent *ev)
- {
-
- QVector line;
- _lines.append(line);
-
-
- QVector &lastLine = _lines.last();
- lastLine.append(ev->pos());
- }
-
- void Mywidget::mouseReleaseEvent(QMouseEvent *ev)
- {
- QVector &lastLine = _lines.last();
- lastLine.append(ev->pos());
- }
-
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
-
- Mywidget w;
- w.show();
-
- return app.exec();
- }
运行结果:
注意:
- 需要在鼠标移动的时候调用update(),使之强制重绘,否则,画面版上不会出现任何效果。
- QVector函数的使用方法和CPP中的Vector方法差不多。
三 在该项目的基础上增加一个按钮
新增一个类MyButton.h
- #ifndef MYBUTTON_H
- #define MYBUTTON_H
-
- #include
-
- class MyButton : public QWidget
- {
- Q_OBJECT
- public:
- explicit MyButton(QWidget *parent = 0);
- MyButton(const QString& text, QWidget* parent = 0);
-
- QRect _rect;
- QString _text;
- bool _pressed;
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
-
- void paintEvent(QPaintEvent *);
-
- signals:
- void clicked();
-
- public slots:
-
- };
-
- #endif // MYBUTTON_H
源文件MyButton.cpp
- #include "MyButton.h"
- #include
- #include
- MyButton::MyButton(QWidget *parent) :
- QWidget(parent), _rect(0, 0, 100, 30), _text(QString())
- {
- _pressed = false;
- this->setGeometry(_rect);
- }
-
- MyButton::MyButton(const QString &text, QWidget *parent):
- QWidget(parent), _text(text), _rect(0, 0, 100, 30)
- {
- _pressed = false;
- this->setGeometry(_rect);
- }
-
- void MyButton::mousePressEvent(QMouseEvent *)
- {
- _pressed = true;
- update();
- }
-
- void MyButton::mouseReleaseEvent(QMouseEvent *ev)
- {
- _pressed = false;
- update();
-
- if(_rect.contains(ev->pos()))
- emit clicked();
-
- }
- void MyButton::paintEvent(QPaintEvent *)
- {
- QPainter p(this);
- if(_pressed)
- p.setBrush(Qt::yellow);
- else
- p.setBrush(Qt::darkGray);
- p.drawRect(_rect);
- p.drawText(_rect, _text, QTextOption(Qt::AlignCenter));
- }
MyWidget,h
- #ifndef MYWIDGET_H
- #define MYWIDGET_H
-
- #include
- #include "MyButton.h"
-
- class MyWidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit MyWidget(QWidget *parent = 0);
-
- MyButton* button;
-
- void paintEvent(QPaintEvent *);
-
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
-
- QVector< QVector > _lines;
-
- signals:
-
- public slots:
- void slotButtonClicked();
- };
-
- #endif // MYWIDGET_H
MyWidget.cpp
- #include "MyWidget.h"
- #include
- #include
- #include
- #include
-
- MyWidget::MyWidget(QWidget *parent) :
- QWidget(parent)
- {
- button = new MyButton("MyButton", this);
- connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
-
-
- }
-
- void MyWidget::slotButtonClicked()
- {
- qDebug() << "button is clicked";
- }
-
- void MyWidget::paintEvent(QPaintEvent *)
- {
- QPainter p(this);
- for(int i=0; i<_lines.size(); ++i)
- {
- const QVector& line = _lines.at(i);
- for(int j=0; j
- {
- p.drawLine(line.at(j), line.at(j+1));
- }
- }
- }
-
- void MyWidget::mouseMoveEvent(QMouseEvent *ev)
- {
- if(_lines.size() == 0)
- {
- QVector line;
- _lines.append(line);
- }
-
- QVector& lastLine = _lines.last();
- lastLine.append(ev->pos());
-
- update();
- }
- void MyWidget::mousePressEvent(QMouseEvent *ev)
- {
- QVector line;
- _lines.append(line);
-
- QVector& lastLine = _lines.last();
- lastLine.append(ev->pos());
- }
- void MyWidget::mouseReleaseEvent(QMouseEvent *ev)
- {
- QVector& lastLine = _lines.last();
- lastLine.append(ev->pos());
- }
-
- #include
- int main(int argc, char** argv)
- {
- QApplication app(argc, argv);
-
- MyWidget w;
- w.show();
-
- return app.exec();
- }
功能:新加了一个按钮
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));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
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));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
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));
}