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

        

  • 相关阅读:
    WebBrowser.ExecWB的完整说明
    jQuery选择器的灵活用法
    Nooice, 首次开通博客园
    【HDU】3663 Power Stations
    【HDU】4069 Squiggly Sudoku
    【FOJ】2076 SUDOKU
    【HDU】3529 Bomberman Just Search!
    【HDU】3909 Sudoku
    【HDU】2780 SuSuSudoku
    【HDU】3111 Sudoku
  • 原文地址:https://www.cnblogs.com/milanleon/p/7338780.html
Copyright © 2011-2022 走看看