找回密码
 立即注册
Qt开源社区 门户 查看内容

Qt 学习笔记-中秋节,QPainter画一颗小心心送给你

2019-9-14 08:12| 发布者: admin| 查看: 770| 评论: 0

摘要: 前言对于程序员来说,中秋节也是一个程序,想把中秋节过好,更想把程序写好,中秋节,QPainter一颗小心心送给你。简介 QPainter类在小部件和其他绘图设备上执行低级绘制。QPainter提供高度优化的功能,以满足大多数 ...
前言

    对于程序员来说,中秋节也是一个程序,想把中秋节过好,更想把程序写好,中秋节,QPainter一颗小心心送给你。

简介

    QPainter类在小部件和其他绘图设备上执行低级绘制。QPainter提供高度优化的功能,以满足大多数绘图GUI程序的要求。它可以绘制从简单线条到复杂形状(如馅饼和和弦)的所有内容。它还可以绘制对齐的文本和像素图。

应用范围

    通常情况下,它会绘制一个“自然”坐标系,但它也可以进行视图和世界转换。QPainter可以对继承QPaintDevice类的任何对象进行操作。QPainter 也可以与 QPrinter 一起使用来打印文件和创建 PDF 文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。

    QPainter的常见用途是在小部件的绘制事件中paintEvent()进行绘制:构造和自定义(例如设置笔或画笔)画家,然后画画。记得在绘图后销毁QPainter对象。 当窗口程序需要升级或者重新绘制时,调用此成员函数。使用 repaint()和 update() 后,调用函数 paintEvent()。

QPainter是一个状态机


    所谓状态机,就是说,QPainter保存的只是各种状态。怎么理解呢?比如,你把颜色设置成红色,那么,直到你重新设置另外的颜色,它的颜色会一直是红色。它的状态不会自己恢复,除非你使用了各种set函数。因此,如果我们在椭圆绘制之后再画一个椭圆,它的样式还会是之前的轮廓和填充,除非你显式地调用了set进行更新。这可能是绘图系统较多的实现方式,因为无论是OpenGL、QPainter还是Java2D,都是这样实现的。

QPainter类的成员角色有:


QPen

用于绘制几何图形的边缘,由颜色,宽度,线风格等参数组成

QBrush 

用于填充几何图形的调色板,由颜色和填充风格组成

QFont

用于文本绘制

QPixmap

绘制图片,可以加速显示,带有屏幕截图,窗口截图等支持,适合小图片

QImage 

绘制图片,可以直接读取图像文件进行像素访问,适合大图片

QBitmap

QPixmap的一个子类,主要用于显示单色位图

QPicture

绘图装置,用于记录和重播Qpainter的绘图指令


QPainter基础图形绘制相关函数:


成员函数

功能

drawPoint

绘制点

drawLine

绘制直线

drawRect

绘制矩形

drawArc

绘制圆弧

drawEllipse

绘制椭圆

drawPie

绘制扇形

drawChord

绘制弦

drawPolygon

绘制多边形

drawRoundedRect

绘制圆角矩形

drawPolyline

绘制折线

drawConvexPolygon

绘制凸多边形

……

……


Qt绘图效率的提高

    Qt在绘制point的时候,一般都直接调用drawPoint()函数,但是在point大数量的时候,会发生卡顿现象,为了提高效率,我们可以设置一个画布pixmap,将所有的基础图形画布上,然后把画布画在控件上。
    #include <QPixmap>void Widget::paintEvent(QPaintEvent *){    QPixmap pixmap(size());  //将画布的大小设置为和widget一样的    QPainter painter(&pixmap);  //在画布上常见一个画家    painter.setBrush(Qt::yellow);    painter.setPen(QPen(Qt::red, 2, Qt::DashLine));    painter.drawEllipse(QPoint(95, 333), 50, 50);    painter.drawText(QPoint(50, 50), "Hello world");    painter.end();      painter.begin(this);  //在Widget上开始绘制    painter.drawPixmap(0, 0, pixmap);  //在控件上绘制pixmap图像    painter.drawLine(QPoint(50, 50), QPoint(60, 10));}

    画♥的例子

        使用drawPoint 一点一点来画,根据心型公式会出现很漂亮的心型,代码如下:
      void Heart::timerEvent(QTimerEvent *){if (m_t > 1000) { update();m_t = 0; } m_x = 16 * m_k * sin(m_k*m_t)*sin(m_k*m_t)*sin(m_k*m_t); m_y = 13 * m_k * cos(m_k*m_t) - 5 * m_k * cos(2 * m_k * m_t) - 2 * m_k * cos(3 * m_k * m_t) - cos(4 * m_k * m_t); m_x += this->width() / 2; m_y -= this->height() / 2; m_y *= -1; update(m_x,m_y,1,1);    m_t += 0.1;}

          如上分析的使用 repaint()和 update() 后,调用函数 paintEvent()。
        void Heart::paintEvent(QPaintEvent *event){QPainter painter(this); painter.setPen(Qt::red); painter.drawPoint(m_x, m_y);}

        效果图



            通过lineTo方法,代码如下,当然也可以去掉下面的/**/,心连心啦,
          void Heart::paintEvent(QPaintEvent *event){double k = 10;QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true);QColor my_color(237, 162, 255, 255);QBrush my_brush(my_color); painter.setPen(Qt::red);/*painter.setBrush(my_brush);*/ painter.translate(this->width()/2, this->height()/2); QPainterPath polygonPath; polygonPath.setFillRule(Qt::WindingFill);float x = 16 * k * sin(0.0)*sin(0.0)*sin(0.0);float y = 13 * k * cos(0.0) - 5 * k*cos(0.0) - 2 * k*cos(0.0) - cos(0.0); polygonPath.moveTo(x, -y);for (double t = 0.01; t < 100; t += 0.05) { x = 16 * k * sin(k*t)*sin(k*t)*sin(k*t); y = 13 * k * cos(k*t) - 5 * k * cos(2 * k * t) - 2 * k * cos(3 * k * t) - cos(4 * k * t); polygonPath.lineTo(x, -y);/*painter.drawPoint(x,-y); painter.drawLine(0,0,x,-y); painter.drawLine(0,0,x+100,-y);*/ } painter.drawPath(polygonPath);}

          效果图



          总结

              Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,同时学习qt 真的要充分利用“Help”,不懂的可以在里面搜索,都有详细的介绍以及举例,当然都是英文的,最后送一颗小♥♥给你。




          推荐阅读

          (点击标题可跳转阅读)

          Qt 学习笔记-强势入门

          Qt 学习笔记-Qt中添加背景图片的方法

          Qt 学习笔记-处理鼠标响应事件

          Qt 纯属娱乐-绘制一个模拟时钟



          关注公众号【技术让梦想更伟大】,获取更多Linux/C/C++/Python/FPGA等原创技术文章。后台免费获取经典电子书籍和视频资源,实时更新,原创不易,请多支持,谢谢!




          ----------------------------------------------------------------------------------------------------------------------
          我们尊重原创,也注重分享,文章来源于微信公众号:技术让梦想更伟大,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
          ----------------------------------------------------------------------------------------------------------------------

          鲜花

          握手

          雷人

          路过

          鸡蛋
          
          公告
          可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了