QT---画弦、矩形、圆、椭圆、QPainterPath一次性画多个、画贝塞尔曲线、画扇形、画弧、裁剪、掩码基本画法

使用qt的QPainter可以绘制出任何你想要的图形,同时也须要一定的功底;这里是个人使用的一些实践例子,以作学习和备忘。本次介绍主要有画弦、矩形、圆、椭圆、QPainterPath一次性画多个、画贝塞尔曲线、画扇形、画弧、裁剪、掩码等。

一、画弦

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setAutoFillBackground(true);
    QPalette pal = palette();
    pal.setBrush(QPalette::Background,Qt::black);
    setPalette(pal); //设置背景色
    
    resize(600,480); //调整大小
    new QPushButton("hello",this); //重写paintEvent不会影响该对象的子控件
}
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    //设置反锯齿
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);
    painter.setPen(Qt::yellow); //设置画笔颜色
   //画弦,该弦在QRect(10.0, 30.0, 80.0, 60.0)的内切椭圆上,并且起始角度为30(3点钟为0度,逆时针为正),跨度为120
    painter.drawChord(10.0, 30.0, 80.0, 60.0,30 * 16, 120 * 16); 
}

可以看到重写paintEvent并为会影响该控件的其它子控件


二、画椭圆和圆

painter.drawEllipse(QPoint(width()/2,height()/2),width()/2 - 10,height()/2 - 10) //有多种画法,这里是指定圆心和x、y轴的半径;当x、y相等时就是画圆了

三、画矩形

    painter.drawRect(width()/2,height()/2,100,100); //以矩形左上角为顶点开画

四、画扇形

painter.drawPie(width()/2 - 50,height()/2 - 50,100,100,30 * 16,120 * 16); //在矩形内切椭圆上画,3点钟为0度,逆时针为正,角度要乘以16(参考文档)

五、QPainter的save()与restore()方法
 

  QPainter painter(this);
    //设置反锯齿
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);
    painter.setPen(Qt::yellow); //设置画笔颜色
    painter.drawPie(width()/2 - 50,height()/2 - 50,100,100,30 * 16,120 * 16); //在矩形内切椭圆上画,3点钟为0度,逆时针为正,角度要乘以16(参考文档)
    painter.save(); //保存painter当前状态,后续紧跟一个restore()方法还原到这个状态
    painter.setPen(Qt::white);
    painter.drawRect(50,50,80,100); //画一个白色的矩形
    painter.restore(); //还原到前一个保存状态
    painter.drawRect(150,150,50,50); //用前一个保存的painter状态,画一个矩形


六、坐标平移   

    painter.setPen(Qt::yellow); //设置画笔颜色
    painter.translate(width()/2,height()/2); //将坐标第原点移动到中心
    painter.drawRect(0,0,100,100);

另外QPainter还有setTransform()方法用于指定某个轴旋转,这个旋转可以让图形从屏幕里面到外边旋转,配合闹钟可以做出动画。


七、resetMatrix()方法,还原到默认坐标系
   

    painter.setPen(Qt::yellow); //设置画笔颜色
    painter.translate(width()/2 - 50 ,height()/2 - 50);
    painter.resetMatrix();
    painter.drawEllipse(0,0,100,100);

八、画边角带弧度的矩形

    painter.setPen(Qt::yellow); //设置画笔颜色
    painter.drawRoundRect(QRect(50,50,100,100),50,50);

九、掩码设置

    QRegion maskRegion(-7,-30,width() + 14,height() + 67);
    setMask(maskRegion.subtracted(QRegion(width()/2 - 70,height()/2 - 30,140,60,QRegion::Ellipse)));

设置为掩码的QRegion将可见,其于的不可见。这里要熟悉QRegion的一些用法

QRegion::intersected(constQRegion &r) const 两个区域相交的部分
QRegion::subtracted(constQRegion &r) const 不包含r的区域
QRegion::xored(constQRegion &r) const 两个区域的并集去掉交集剩下的部分

另外支持运算符重载意义和这个一样的。


十、裁剪
 

   painter.setPen(Qt::yellow); //设置画笔颜色
    painter.setClipRegion(QRegion(width()/2 - 100,height()/2 - 100,200,200)); //设置一个裁剪区域
    painter.setPen(Qt::white);
    painter.drawRect(painter.clipRegion().boundingRect());
    painter.setPen(Qt::yellow);
    painter.setBrush(QBrush(Qt::red));
    painter.drawEllipse(width()/2 - 80,height()/2 - 80,200,200); //超出裁剪区域的不画

setClipRegion()方法会自动设置setClipping()为true。当此次绘画结束后;如果后续绘画的区域没有在裁剪区域内,则不会显示;这时需要在裁剪绘画结束
后调用setClipping()传入false,使裁剪失效,这样就可以正常显示了


十一、画圆环
 

    painter.setPen(Qt::yellow); //设置画笔颜色
    QRegion r1(width()/2 - 50,height()/2 - 50,100,100,QRegion::Ellipse);
    QRegion r2(width()/2 - 100,height()/2 - 100,200,200,QRegion::Ellipse);
    painter.setClipRegion(r2 - r1);
    painter.fillRect(r2.boundingRect(),QBrush(Qt::red));

这里我想到的有两种方法:一、是画一个红色的大圆,再到中间画一个黑色(或透明)的小圆。
                                 二、是构造一个圆环的QRegion使用QPainter的setClipRegion()方法使得只有在圆环区域内图形才能显示。
这里我使用的是第二种方法。

十二、用QPainterPath一次画多个图案
   

    painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath path;
    path.addText(10,10,painter.font(),"Qt");
    path.moveTo(10,50);
    path.lineTo(120,50);
    path.addRoundedRect(10,80,80,80,5,5);
    painter.drawPath(path);

QPainterPath默认的起点在(0,0),在lineTo()之后,会将path的自动起点位置移到lineTo的点。addRect()或者addRoundedRect()之后会自动将起点移到Rect的左上角顶点

十三、使用QPainterPath的arcMoveTo和arcTo画弧或扇形
   

 painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath path;
    path.arcMoveTo(width()/2 - 100,height()/2 - 100, 200,200,30); //将path的起点移到一个椭圆(以3点钟为0度,逆时针为正)距离角度0点为30度的椭圆上,该椭圆是rect(100,280,120,120)的内切椭圆
    path.arcTo(width()/2 - 100,height()/2 - 100, 200,200,30,120);
    painter.drawPath(path);

arcMoveTo其实就是为了设置arcTo绘画的起点,两个函数都是以一个矩形的内切椭圆的形式传参。如果是扇形的话
    painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath path;
    path.moveTo(width()/2,height()/2);
    path.arcTo(width()/2 - 100,height()/2 - 100, 200,200,30,120);
    painter.drawPath(path);

我们只需要设置起画起点在椭圆中心就可以了,因为arcTo是先从QPainterPath起点到以传入参数应该起画的点之间连接再开画。
这里并不是一个完整的扇形,因为arcTo是画弧的;画完不会连接此次绘画的起点,这里需要我们手动连接,最简单的方法是调用

  QPainterPath的closeSubpath()直接将Path绘画终点与起点闭合。
   painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath path;
    path.moveTo(width()/2,height()/2);
    path.arcTo(width()/2 - 100,height()/2 - 100, 200,200,30,120);
    path.closeSubpath();
    painter.drawPath(path);

十四、使用QPainterPath画贝塞尔曲线
 

    painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath cubPath;
    cubPath.cubicTo(170,50,90,200,width(),height());//传入点1(170,50),点2(90,200),endPoint(width(),heigt())
    cubPath.addEllipse(170 - 3,50 - 3,6,6); //以点1为圆心画圆
    cubPath.addText(180,60,painter.font(),QStringLiteral("Point1")); //标记点1
    cubPath.addEllipse(90 - 3,200 - 3,6,6);//以点2为圆心画圆
    cubPath.addText(100,210,painter.font(),QStringLiteral("Point2"));//标记点2
    painter.drawPath(cubPath);

如果加个画刷颜色就可以变成这样

    painter.setPen(Qt::yellow); //设置画笔颜色
    QPainterPath cubPath;
    cubPath.cubicTo(170,50,90,200,width(),height());//传入点1(170,50),点2(90,200),endPoint(width(),heigt())
    cubPath.addEllipse(170 - 3,50 - 3,6,6); //以点1为圆心画圆
    cubPath.addText(180,60,painter.font(),QStringLiteral("Point1")); //标记点1
    cubPath.addEllipse(90 - 3,200 - 3,6,6);//以点2为圆心画圆
    cubPath.addText(100,210,painter.font(),QStringLiteral("Point2"));//标记点2
    painter.setBrush(QBrush(Qt::lightGray));
    painter.drawPath(cubPath);


效果是不是还可以

以上就是我关于QPainter及QPainter相关的一些类的学习,用以上的这些基础图形再加上闹钟,QPropertyAnimation,QTranslateform就可以做出很多酷弦的效果。祝工作愉快。

你可能感兴趣的:(QT---之painter相关)