zoukankan      html  css  js  c++  java
  • 《QT Creator快速入门》第十章:2D绘制(1)

    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, r.top()), QPoint(0, r.bottom()));

        

             再次修改开始点和结束点的代码和效果如下:

    QLinearGradient linearGradient(r.topLeft(), 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类可以实现类似我们在桌面上拖动鼠标出现的橡皮筋线,如图所示:

        

  • 相关阅读:
    poj 1579(动态规划初探之记忆化搜索)
    hdu 1133(卡特兰数变形)
    CodeForces 625A Guest From the Past
    CodeForces 625D Finals in arithmetic
    CDOJ 1268 Open the lightings
    HDU 4008 Parent and son
    HDU 4044 GeoDefense
    HDU 4169 UVALive 5741 Wealthy Family
    HDU 3452 Bonsai
    HDU 3586 Information Disturbing
  • 原文地址:https://www.cnblogs.com/milanleon/p/7338780.html
Copyright © 2011-2022 走看看