Qt中的二维绘图基本功能是使用Qpainter在绘图设备上进行绘图,绘图设备由QpainterDevice提供,QPaintDevice是一个二维空间的抽象,可以使用QPainter在其上进行绘制,它是所有可以进行绘制的对象的基类。QPainterDevice的子类主要有QWidget, QPixmap,QPicture,QImage,QPinter,QOpenGIPainterDevice,这些设备相当于为QPainter提供了一个画布。通过绘制一些基本的图形,如点,线,圆组成自己需要的图图件,形,得到的图形是不可交互的。

Qt中的Graphics View架构,使用QGraphicsView,QGraphicsScene,QGraphicsItem类绘图,在一个场景中可以绘制,且图件是可以交互的。

1. QPainter基本绘图:

在绘图系统中,主要通过QPainter完成具体的绘图操作,QPaintDevice是一个可以用QPainter进行绘图的抽象二维画布。QPainterEngine为QPainter提供在不同设备上进行绘图的接口,QPainterEngine类一般只在QPainter类和QPaintDevice类的内部使用,一般不需要我们去操作它。

QPainter在一个Paint Event事件函数中进行绘图,从画布(QWidget, QPixmap, QPicture, QImage, QPinter,     QOpenGIPainterDevice )继承的类都有Paint Event事件函数。例如创建一个Widget窗口,进行绘图,则这个Widget窗口就是需要使用的绘图设备。

绘图的区域就是Widget内部的区域,区域内的坐标系统的单位是像素,左上角为原点(0,0),向右是X轴正向,向下是Y轴正向。绘图区域的大小可以由Widget::width()以及Widget::height()得到。

QPainter绘图的属性:
1. pen属性:是一个QPen对象,用于控制线条的颜色,宽度,线型等属性

2. brush属性:是一个QBrush对象,控制区域填充特性,如颜色,填充方式,渐变特性

3. font:QFont对象,用于绘制文字时控制文字的属性,字体,大小等

1. 首先声明绘图事件处理函数:

protected:void paintEvent(QPaintEvent* event);

2.在paintEvent()函数中编写绘制图像的代码:

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();QRect rect(width/4, height/4, width/2, height/2);   // 中间区域矩形框// QPainter属性 pen,brush,fontQPen pen;pen.setWidth(3);    // 设置线宽pen.setColor(Qt::blue);pen.setStyle(Qt::SolidLine);   // 线的样式pen.setCapStyle(Qt::FlatCap);        // 线条的端点样式pen.setJoinStyle(Qt::BevelJoin);     // 连接点的样式painter.setPen(pen);              // 设置QPainter的pen属性// brush属性QBrush brush;brush.setColor(Qt::green);        // 填充颜色brush.setStyle(Qt::SolidPattern);   // 填充样式painter.setBrush(brush);// 绘图painter.drawRect(rect);// 绘制直线pen.setColor(Qt::red);pen.setCapStyle(Qt::FlatCap);pen.setJoinStyle(Qt::BevelJoin);painter.setPen(pen);painter.drawLine(QPoint(5, 5), QPoint(width-10, height-10));
}

绘图结果:

关于绘制图像中的抗锯齿,可以参考博客:https://blog.csdn.net/xiezhongyuan07/article/details/97116491

同时,可以擦除矩形中填充的颜色,以及重新填充:

painter.eraseRect(rect);   // 擦除矩形区域的内容
// 可以重新填充矩形区域
brush.setColor(Qt::black);
painter.fillRect(rect, brush);

QPainter的三个属性介绍:

1. QPen的属性:

Qpen主要用于在绘图时对线条进行控制,包括线宽,颜色,线型的。

QPen主要的接口函数有:

更改器:(设置属性)

1.pen.setColor(Qt::red);                        设置颜色
2.pen.setCapStyle(Qt::FlatCap);           设置端点样式
3. pen.setJoinStyle(Qt::BevelJoin);       设置连接样式

4. pen.setWidth()                                  设置宽度

5. pen.setStyle()                                   设置样式

访问器:(获取属性)

1.pen.color(Qt::red);                             获取pen的颜色
2.pen.capStyle(Qt::FlatCap);                       获取端点样式
3. pen.joinStyle(Qt::BevelJoin);           连接样式

4. pen.width()                                       宽度

5. pen.style()                                   样式

线条样式主要有六种:
1. SolidLine

2. DashLine

3. DotLine

4. DashDotLine

5. DashDotDotLine

6. CustomDashLine

7.NoPen

端点样式有三种:

1. SquareCap

2. FlatCap

3. RoundCap

连接样式也有三种:

1. BevelJoin

2. MiterJoin

3. RoundJoin

2. QBrush介绍:

QBrush定义了QPainter绘图时的填充性能,包括颜色,填充样式,填充材质。

QBrush的主要函数有以下几种:
void    setColor ( Qt::GlobalColor color )
void    setStyle ( Qt::BrushStyle style )
void    setTexture ( const QPixmap & pixmap )
void    setTextureImage ( const QImage & image )

填充样式setStyle()的参数是一个枚举类型,主要有以下几种:

例如,用几种不同的方式填充矩形区域:

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();QRect rect(width/4, height/4, width/2, height/2);   // 中间区域矩形框// brush属性QBrush brush;brush.setColor(Qt::red);        // 填充颜色// brush.setStyle(Qt::SolidPattern);   // 填充样式// brush.setStyle(Qt::Dense7Pattern);// brush.setStyle(Qt::CrossPattern);brush.setStyle(Qt::FDiagPattern);painter.setBrush(brush);// 绘图painter.drawRect(rect);}

QBrush填充渐变颜色:

Qt中有三种渐变的效果,如下图所示:

1. QLinearGradient

线性渐变颜色,可以指定一个起点颜色,终点颜色,还可以指定中间颜色,起点和终点之间可以进行插值计算,得到线性渐变的填充颜色。

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();QRect rect(width/4, height/4, width/2, height/2);   // 中间区域矩形框QLinearGradient linearGrident(width/4, height/4, width/2, height/2);    // 指定渐变区域linearGrident.setColorAt(0, Qt::red);linearGrident.setColorAt(0.5, Qt::yellow);linearGrident.setColorAt(1, Qt::blue);// brush属性QBrush brush;painter.setBrush(linearGrident);// 绘图painter.drawRect(rect);}

填充效果:

2.QConicalGradient: 圆锥形渐变,即围绕一个中心点逆时针生成渐变颜色。

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();QConicalGradient gradient(width/2, height/2, 0);    // 填充参数参数cx, cy, start_angle,gradient.setColorAt(0, Qt::red);                    // 起始角度的位置,与线性渐变一样,也是采用相对位置gradient.setColorAt(0.4, Qt::green);gradient.setColorAt(0.6, Qt::yellow);gradient.setColorAt(1, Qt::black);painter.setBrush(gradient);painter.drawRect(this->rect());  // 画圆的区域}

填充效果:

3. QRadialGradient: 辐射渐变填充,有简单辐射渐变和扩展辐射渐变两种方式,简单辐射渐变是在一个圆内一个焦点和一个端点之间生成渐变颜色,扩展辐射渐变是在一个焦点圆和一个中心圆之间生成渐变颜色。

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();// 径向渐变 c_x, c_y, radius, fx, fy 其中fx,fy为焦点// c_x, c_y是辐射的中心点,radius是辐射半径QRadialGradient gradient(width/2, height/2, qMax(width/4, height/4), width/2, height/2);    // 径向渐变gradient.setColorAt(0, Qt::red);gradient.setColorAt(1, Qt::black);                  // 这里使用的是逻辑坐标 0开始位置 1结束位置// gradient.setSpread(QGradient::PadSpread);       // 设置渐变区域之外的渐变方式,即延展方式// gradient.setSpread(QGradient::RepeatSpread);gradient.setSpread(QGradient::ReflectSpread);painter.setBrush(gradient);painter.drawRect(this->rect());  // 画圆的区域}

同时,QRadialGradient需要通过setSpread()函数设置延展方式,也就是填充区域意外的填充方式,共有三种方式:

下面是填充的效果:

PadSpread:

RepeatSpread:

ReflectSpread:

QPainter绘制基本图形元件:

QPainter可以绘制包括点,直线,曲线,矩形,圆弧等各种基本线条。具体的函数以及参数可以参考Qt文档:(文档部分)

坐标系统和坐标变换:

QPainter在窗口上绘图的默认坐标是绘图设备的物理坐标,为了绘图方便,QPainter提供了一些坐标变换功能,通过平移,旋转等坐标变换,得到一个逻辑坐标系统,使用逻辑坐标系统在某些时候绘图会更加方便。

常用的坐标变换:
1. 平移变换:
void translate(dx, dy):表示将坐标系统的原点移动到(dx, dy)位置。移动的单位为像素。

2. 坐标旋转:

void rotate(angle): 将坐标系统绕坐标原点旋转指定的角度。angle>0表示顺势正旋转,angle<0表示逆时针旋转。

3.缩放:

void scale(sx, sy): 表示缩放,sx,sy表示沿着x,y轴的缩放比例。参数大于1表示放大,参数小于1表示缩小。

4. 状态保存于恢复:
在进行坐标变换的时候,QPainter内部会有一个坐标变换的矩阵,用save()函数保存坐标的状态。用restore()表示恢复保存的坐标状态。这两个函数必须配对使用。resetTransform表示复位所有的变换操作。

例子:

void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);    // this代表Widget,及绘图设备painter.setRenderHint(QPainter::Antialiasing);    // 绘画普通图形启用反走样, 即开启抗锯齿painter.setRenderHint(QPainter::TextAntialiasing);    // 绘画文字反走样, 即开启抗锯齿int width = this->width();      // 获取绘图区域的大小int height = this->height();// 生成五角星的五个顶点坐标int radius = 100;      // 半径const double Pi = 3.1415926;double deg = 360.0 / 5 * Pi / 180.0;QPoint points[5] = {QPoint(radius, 0),QPoint(radius * cos(deg), radius * sin(deg)),QPoint(radius * cos(2*deg), radius * sin(2*deg)),QPoint(radius * cos(3*deg), radius * sin(3*deg)),QPoint(radius * cos(4*deg), radius * sin(4*deg))};// 设置字体QFont font;font.setPointSize(12);font.setBold(true);painter.setFont(font);// 设置画笔QPen pen;pen.setWidth(2);       // 设置线宽pen.setColor(Qt::blue);     // 设置颜色pen.setStyle(Qt::SolidLine);    // 设置线型pen.setCapStyle(Qt::FlatCap);pen.setJoinStyle(Qt::BevelJoin);painter.setPen(pen);// 设置画刷QBrush brush;brush.setColor(Qt::red);brush.setStyle(Qt::SolidPattern);painter.setBrush(brush);// painter_path, 可以重复使用QPainterPath path;path.moveTo(points[0]);   // 起始点path.lineTo(points[2]);path.lineTo(points[4]);path.lineTo(points[1]);path.lineTo(points[3]);path.closeSubpath();     // 闭合路径,相当于 path.lineTo(points[0]);// 添加文本path.addText(points[0], font, "1");path.addText(points[1], font, "2");path.addText(points[2], font, "3");path.addText(points[3], font, "4");path.addText(points[4], font, "5");// 保存坐标状态painter.save();painter.translate(width/4, height/4);    // 平移painter.drawPath(path);//  恢复坐标painter.restore();painter.translate(width/2, height/2);    // 平移painter.scale(0.6, 0.6);        // 缩放,缩小操作painter.rotate(30);             // 旋转painter.drawPath(path);         // 这里的path重复利用了}

绘制效果图:

QPainterPath可以记录几个点的连线过程,可以对绘制复杂图像的过程进行记录,便于重复使用。

C++ Qt学习笔记(4)绘图相关推荐

  1. Qt 学习笔记(5)绘图 五子棋游戏

    在上一篇博客C++ Qt学习笔记(4)绘图中介绍了Qt中的绘图方法,基于上一篇的博客的知识,使用QPainter设计一个五子棋的棋盘,后续会完成五子棋的游戏设计. 1. 棋盘的设计 首先需要绘制棋盘的 ...

  2. QT学习笔记(十三):绘制图像

    QT学习笔记(十三):绘制图像 paintEvent() 事件源码添加: #include <QPainter> #include <QImage> #include < ...

  3. Qt学习笔记,Qt国际化

    Qt学习笔记,Qt国际化 Qt国际化步骤: 第一步:设置.pro文件,加入TRANSLATIONS为国际化做准备 TRANSLATIONS = language/language_en.ts\     ...

  4. Qt学习笔记,Qt程序架构设计要旨

    Qt学习笔记,Qt程序架构设计要旨 时间过得很快,转眼学习Qt已经有一个多月了,对Qt的学习也在不断的深入中.自己手下的code也很多了,不过不得不说,还有很多的部分没有接触过,比如网络编程,2D,3 ...

  5. Qt学习笔记之MySQL数据库

    一.MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQ ...

  6. Qt学习笔记之数据库

    一.数据库简介 1.1.数据和数据库(DB) 用计算机进行数据处理,首先就要把信息以数据形式存储到计算机中,故数据是可以被计算机接受和处理的符号.根据所表示的信息特征不同,数据有不同的类别,如数字.文 ...

  7. Qt学习笔记之文件处理

    Qt提供了通用的文件处理类QFile和处理文本的QTextStream类和处理二进制数据的QDataStream类,这些流操作极大地方便了对文件的督促存储.对文件信息和目录进行操作的类是QfileIn ...

  8. Qt学习笔记之国际化

    国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. 1. 相关的Qt类和AP ...

  9. Qt学习笔记之 字符串类型小结

    1. Qt常用字符串类型 1.1 QString QString是Unicode编码的字符串,存储一系列16位的QChar,每一个QChar对应一个Unicode 4.0编码的字符,详见<Qt学 ...

  10. Qt学习笔记,再次分析EVA源码之后得出的结论-QListView,QListViewItem(Qt3);Q3ListView,Q3ListViewItem(Qt4)...

    Qt学习笔记,再次分析EVA源码之后得出的结论-QListView,QListViewItem(Qt3);Q3ListView,Q3ListViewItem(Qt4) 今天再次分析了Eva的源码,也看 ...

最新文章

  1. php 支付宝手机端_PHP 手机支付宝接口
  2. 关于自动寻径和图、邻接表的学习和启发
  3. codevs 1066 引水入城(DFS+DP)
  4. mysql高可靠部署_可能是我见过最好的 MySQL 高可用解决方案 MySQL InnoDB Cluster 中文教程!...
  5. Openwrt中luci配置页面cbi小记
  6. 链表数据结构原理图/内存结构图/内存图
  7. Android中级之网络数据解析一之Json解析
  8. Spark SQL中的DataFrame
  9. 电信移动联通广电喜提5G牌照,5G手机明年爆发
  10. 快播创始人王欣成立人工智能公司
  11. Solaris系统环境变量声明方法
  12. Nr,GenBank, RefSeq, UniProt 数据库的异同
  13. PowerGUI错误-Microsoft SharePoint is not supported with version 4 of the Microsoft .Net Runtime
  14. 广域通信网知识点笔记
  15. php游戏传奇,GitHub - esons/pmir2: php,swoole,mirserver,mir2,传奇2,服务器,游戏服务器
  16. 【数字电路】期末不挂科复习笔记
  17. php微信卡包代码,微信卡券,在卡包中跳转到小程序的字段怎么填写
  18. Qt音视频开发12-mpv解码播放
  19. linux su 资源不可用,CentOS 6/Linux su: 无法设置用户ID: 资源暂时不可用
  20. android 查看视频大小,android mediaplayer 视频修改视频大小 (屏幕尺寸mediaPlayer =......

热门文章

  1. 大数据_Flink_流式处理_简介_流数据处理的应用行业---Flink工作笔记0003
  2. OAuth2.0_授权服务配置_令牌服务和令牌端点配置_Spring Security OAuth2.0认证授权---springcloud工作笔记143
  3. 数据库工作笔记004---mysql对结果字段进行判断的函数_Case when等
  4. jsp,servlet中文乱码问题
  5. 【转贴】gdb中的信号(signal)相关调试技巧
  6. ftk学习记(对话框篇)
  7. cilium插件测试_Cilium网络概述
  8. parallels desktop 缺少组件_厦门100W5折电脑太阳能光伏组件,100W293mm*418mm*70mmMP4车载太阳能板...
  9. php在登录页面使用ajax,使用Ajax安全的登录界面
  10. vmware虚拟化服务器cpu超线程,VMware vSphere的配置方法最佳方案从而提高性能