1、QPainter
使用QPainter来进行绘制操作,常用的有:
QPainter::drawPoint:绘制点
QPainter::drawLine:绘制线
QPainter::drawRect:绘制矩形
QPainter::drawRoundedRect:绘制圆角矩形
QPainter::drawPolyline:绘制折线,即多个首尾相连的线
QPainter::drawPolygon:绘制折线形,即多边形
QPainter::drawEllipse:绘制圆形
QPainter::drawArc:绘制圆弧
QPainter::drawPie:绘制扇形
QPainter::drawChord:绘制弦
QPainter::drawConvexPolygon:绘制凸多边形
QPainter可以剪切一个矩形、区域、路径,分别使用setClipRect()、setClipRegion()、setClipPath()函数来实现,然后就只能在剪切的区域内进行绘制,超出剪切区域的话不会显示绘制的内容:void Widget::Widget::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
painter.setClipRect(10, 0, 20, 10);
painter.drawText(10, 10, "test"); //注意y坐标是绘制文字的baseline
}

void MainWindow::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
QBrush brush(QColor(255, 0, 0));//画刷颜色为红色,画刷填充模式为Qt::SolidPattern
painter.setBrush(brush);
painter.setPen(Qt::blue); //画笔颜色为蓝色
painter.drawRect(50, 50, 100, 80);
}

drawRect()的绘制位置有时会有些特殊,下面是使用画笔宽度分别为1 (默认)、2、3的情况下进行的边框绘制代码:
void MainWindow::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
//画笔宽度为1的话(默认),实际绘制的大小会比传入的大小+1
QPen pen(Qt::red, 1);
painter.setPen(pen);
painter.drawRect(QRect(0, 0, width() - 1, height() - 1));
//画笔宽度为2的话,实际绘制的位置会比传入的位置-1,大小会比传入的大小+2
QPen pen(Qt::red, 2);
painter.setPen(pen);
painter.drawRect(QRect(1, 1, width() - 2, height() - 2));
//画笔宽度为2的话,实际绘制的位置会比传入的位置-1,大小会比传入的大小+3
QPen pen(Qt::red, 3);
painter.setPen(pen);
painter.drawRect(QRect(1, 1, width() - 3, height() - 3));
}



2、paintEvent()
一般在重绘事件处理函数paintEvent中进行绘制工作,如绘制线:


void Widget::paintEvent(QPaintEvent* )
{
QPainter painter;
painter.begin(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
painter.end();
}View Code

也可以在QPainter对象的构造函数中直接传入QPaintDevice,不用再调用begin和end:


void Widget::paintEvent(QPaintEvent* )
{
QPainter painter(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
}View Code
3、画笔
可以使用画笔来改变线条的颜色、宽度、风格等:


void Widget::paintEvent(QPaintEvent* )
{
//使用画笔绘制线
QPainter painter(this);
QPen pen;
pen.setColor(Qt::red);//画笔颜色
pen.setWidth(10);//画笔宽度
pen.setStyle(Qt::DashLine);//画笔类型:实线Qt::SolidLine、虚线Qt::DashLine、点线Qt::DotLine等
pen.setCapStyle(Qt::RoundCap);//画笔端点风格,直形Qt::FlatCap,圆形Qt::RoundCap
//pen.setJoinStyle(Qt::RoundJoin);//两个线条端点连接的风格
painter.setPen(pen);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
}View Code

其中QPen::setJoinStyle()可以设置两条线相交的风格,其不同参数的效果如下所示:

绘制矩形和圆弧:



void Widget::paintEvent(QPaintEvent* )
{
QPainter painter(this);
QPen pen(Qt::green, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);//在构造函数中设置画笔颜色、宽度等
painter.setPen(pen);
QRectF rectF(70.0, 40.0, 80.0, 60.0);//所在矩形
int startAngle = 0 * 16;//起始角度 * 16,0度为3点钟方向
int spanAngle = 180 * 16;//跨越角度 * 16,逆时针
painter.drawRect(rectF);
pen.setColor(Qt::red);//改变画笔颜色
painter.setPen(pen);
painter.drawArc(rectF, startAngle, spanAngle);
}View Code

4、画刷
画刷有多种填充模式,如下所示:

可以用QBrush()、setStyle()、setTexture()来设置或改变画刷的填充模式。下面为先设置画笔为绿色,然后使用不同的画刷类型来绘制矩形,圆形,四边形,最后还原画刷为初始再绘制一个矩形:


void Widget::paintEvent(QPaintEvent* )
{
QPainter painter(this);
QPen pen(QColor(0, 255, 0));
pen.setWidth(2);
painter.setPen(pen);
QBrush brush(QColor(0, 0, 255));//画刷颜色为蓝色,画刷填充模式为Qt::SolidPattern
painter.setBrush(brush);
painter.drawRect(60, 20, 50, 40);
brush.setStyle(Qt::Dense4Pattern);//画刷填充模式为Qt::Dense4Pattern
painter.setBrush(brush);
painter.drawEllipse(120, 20, 50, 50);
brush.setTexture(QPixmap("F://draw.png"));//设置画刷纹理为使用一个图片
painter.setBrush(brush);
static const QPointF points[4] = {
QPointF(170.0, 80.0),
QPointF(190.0, 10.0),
QPointF(250.0, 30.0),
QPointF(290.0, 70.0)
};
painter.drawPolygon(points, 4);
brush.setStyle(Qt::NoBrush);//画刷填充模式为Qt::NoBrush
painter.setBrush(brush);
painter.drawRect(300, 20, 50, 40);
}View Code



void Widget::Widget::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
QBrush brush(QColor(255, 0, 0));
painter.setBrush(brush);
//绘制三角形
const QPoint points[3] = {
QPoint(100, 20),
QPoint(150, 40),
QPoint(200, 20)
};
painter.drawPolygon(points, 3);
const QPoint points2[4] = {
QPoint(100, 60),
QPoint(150, 80),
QPoint(200, 60)
};
painter.drawPolyline(points2, 3);
}View Code

可以使用fillRect()来直接绘制一块矩形区域,使用eraseRect()来擦除一块矩形区域:


void Widget::paintEvent(QPaintEvent* )
{
QPainter painter(this);
painter.fillRect(60, 20, 150, 100, QBrush(Qt::darkYellow));
}View Code

5、渐变色
QGradient渐变色类用来跟QBrush一起来实现渐变色填充,QGradient有三个派生类,即三种渐变色填充方式:QLinearGradient线性渐变、QRadialGradient辐射渐变、QConicalGradient锥形渐变。
①、QLinearGradient线性渐变
QLinearGradient线性渐变就是在开始点和结束点之间填充颜色,使用如下:


void Widget::paintEvent(QPaintEvent* )
{
//矩形区域
QRect r(20, 20, 260, 260);
//线性渐变,设置起点和终点
QLinearGradient linearGradient(QPoint(r.left(), 0), QPoint(r.right(), 0));
//设置一半黄色,一半红色
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(1, Qt::red);
//添加渐变到QPainter
QPainter painter(this);
painter.setBrush(linearGradient);
//绘制矩形
painter.drawRect(r);
}View Code

我们修改开始点和结束点的代码和效果如下:
QLinearGradient linearGradient(QPoint(0, ()), QPoint(0, r.bottom()));

再次修改开始点和结束点的代码和效果如下:
QLinearGradient linearGradient(Left(), r.bottomRight());

还可以设置多种颜色:


void Widget::paintEvent(QPaintEvent* )
{
//矩形区域
QRect r(20, 20, 260, 260);
//线性渐变,设置起点和终点
QLinearGradient linearGradient(QPoint(r.left(), 0), QPoint(r.right(), 0));
//设置三分之一黄色,三分之一红色,三分之一绿色
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(0.5, Qt::red);
linearGradient.setColorAt(1, Qt::green);
//添加渐变到QPainter
QPainter painter(this);
painter.setBrush(linearGradient);
//绘制矩形
painter.drawRect(r);
}View Code

还可以对Cpen进行渐变色设置,使绘制的线条、文字等也呈渐变色显示,代码及效果如下:


void Widget::paintEvent(QPaintEvent* )
{
//线性渐变,设置起点和终点
QLinearGradient linearGradient(QPoint(30, 0), QPoint(210, 0));
//设置一半黄色,一半红色
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(1, Qt::red);
//添加渐变到Qen
QPainter painter(this);
painter.setPen(QPen(linearGradient, 5));
//绘制线条和文字
painter.drawLine(30, 80, 210, 80);
painter.drawText(30, 130, "Welcome to the world of QT!");
}View Code

还可以使用QLinearGradient::setSpread()用来设置渐变区域以外区域的颜色模式。
②、QRadialGradient辐射渐变
QRadialGradient的构造函数QRadialGradient ( const QPointF & center, qreal radius, const QPointF & focalPoint )分别用来初始化圆心,半径,和焦点。然后分别由焦点向圆环、圆环向焦点填充各自的颜色。焦点位置为0, 圆环位置为1,示例代码及效果如下:


void Widget::paintEvent(QPaintEvent* )
{
QRadialGradient radialGradient(QPointF(200, 190), 50, QPointF(200, 190));//设置圆心,半径,和焦点
radialGradient.setColorAt(0, QColor(255, 0, 0));//设置焦点颜色
radialGradient.setColorAt(1, QColor(0, 0, 0));//设置圆环颜色
QPainter painter(this);
painter.setBrush(radialGradient);
painter.drawEllipse(QPointF(200, 190), 50, 50);
}View Code

修改焦点位置的代码及效果如下:
QRadialGradient radialGradient(QPointF(200, 190), 80, QPointF(250, 190));//设置圆心,半径,和焦点

③、锥形渐变QConicalGradient
锥形渐变QConicalGradient的示例代码及效果如下:


void Widget::paintEvent(QPaintEvent* )
{
QConicalGradient conicaGradient(QPointF(350, 190), 60);
conicaGradient.setColorAt(0.2, Qt::cyan);
conicaGradient.setColorAt(0.9, Qt::black);
QPainter painter(this);
painter.setBrush(conicaGradient);
painter.drawEllipse(QPointF(350, 190), 50, 50);
}View Code

6、绘制路径
创建一个QPainterPath路径对象后就会以坐标原点为当前点,可以通过moveTo()改变当前点,通过lineTo()、arcTo()、QuadTo()、cublicTo()将直线、弧线、二次贝塞尔曲线、三次贝塞尔曲线加入到路径中,这时候当前点会自动改变为这些图形的终点。还可以使用addRect()、addEllipse()、addText()、addPath()等添加图形或文字:


void Widget::Widget::paintEvent(QPaintEvent* pe)
{
QPainterPath path;
path.moveTo(20, 80);
path.lineTo(20, 30);//绘制直线
path.cubicTo(80, 0, 50, 50, 80, 80);//绘制贝塞尔曲线
QPainter painter(this);
painter.drawPath(path);
}View Code

根据三个点(起点、中间点、终点)绘制的贝塞尔曲线:

根据四个点(起点、两个中间点、终点)绘制的贝塞尔曲线 :



void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPainterPath path;
//添加一条直线
path.moveTo(50, 280);
path.lineTo(50, 230);
//添加一条贝塞尔曲线
path.cubicTo(QPointF(105, 40), QPointF(115, 80), QPointF(120, 60));
//添加一条直线:从贝塞尔曲线终点到(130, 130)
path.lineTo(130, 130);
//添加一个圆:以(130, 130)为圆点
path.addEllipse(QPoint(130, 130), 30, 30);
//绘制路径
painter.drawPath(path);
}View Code



void Widget::Widget::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
QBrush brush(QColor(255, 0, 0));
painter.setBrush(brush);
//绘制线条+三角形
QPainterPath path;
path.moveTo(150, 80);
path.lineTo(150, 120);
QPolygonF poy({QPointF(100.0, 120.0), QPointF(150.0, 140.0), QPointF(200.0, 120.0), QPointF(100.0, 120.0)});
path.addPolygon(poy);
painter.drawPath(path);
}View Code

QPainter::translate()可以平移坐标系统。
填充路径的时候有两种模式:Qt::OddEvenFill(默认)、Qt::WindingFill,两种填充效果的代码及效果如下:


void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPainterPath path;
path.addEllipse(10, 50, 100, 100);
path.addRect(50, 100, 100, 100);
painter.setBrush(Qt::cyan);
painter.drawPath(path);
painter.translate(180, 0);
path.setFillRule(Qt::WindingFill);
painter.drawPath(path);
}View Code

7、QRubberBand
利用QRubberBand类可以实现类似我们在桌面上拖动鼠标出现的橡皮筋线,如图所示:

















