简述

Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这三个类。

  • QPainter用来执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice显示图形(线、形状、渐变等)、文本和图像。

  • QPaintDevice不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture等多种界面中间,必须使用QPaintDevice。

  • QPaintEngine提供了一些接口,可以用于QPainter在不同的设备上进行绘制。

绘图系统由QPainter完成具体的绘制操作,QPainter类提供了大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter也支持线性变换,例如平移、旋转、缩放。

QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。QPainter也可以与QPrinter一起使用来打印文件和创建PDF文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。

QPainter一般在部件的绘图事件paintEvent()中进行绘制,首先创建QPainter对象,然后进行图形的绘制,最后记得销毁QPainter对象。当窗口程序需要升级或者重新绘制时,调用此成员函数。使用repaint()和update()后,调用函数paintEvent()。

下面通过简单的示例来介绍成员函数paintEvent()的使用方法。

绘制文本

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this);
// 设置画笔颜色
painter.setPen(QColor(0, 160, 230)); // 设置字体:微软雅黑、点大小50、斜体
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(50);
font.setItalic(true);
painter.setFont(font); // 绘制文本
painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

首先为该部件创建了一个QPainter对象,用于后面的绘制。使用setPen()来设置画笔的颜色(淡蓝色)。通过使用QFont来构建我们想要的字体,setFamily()设置字体为微软雅黑、setPointSize()设置点大小30、setItalic()设置斜体, 然后通过setFont()来设置字体,最后调用drawText()来实现文本的绘制,这里的rect()是指当前窗体的显示区域,Qt::AlignCenter指文本居中绘制。

绘制直线

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this);
// 反走样
painter.setRenderHint(QPainter::Antialiasing, true);
// 设置画笔颜色
painter.setPen(QColor(0, 160, 230));
// 绘制直线
painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2));
}

首先我们通过setRenderHint()来设置反走样,要么绘制出来的线条会出现锯齿,调用setPen()来设置画笔颜色(淡蓝色)。最后调用drawLine()来实现直线的绘制,其中QPointF(0, height())是指直线的起点坐标、QPointF(width() / 2, height() / 2)是指直线的终点坐标。

绘制矩形

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this); // 反走样
painter.setRenderHint(QPainter::Antialiasing, true);
// 设置画笔颜色、宽度
painter.setPen(QPen(QColor(0, 160, 230), 2));
// 设置画刷颜色
painter.setBrush(QColor(255, 160, 90));
painter.drawRect(50, 50, 160, 100);
}

首先我们使用setPen()来设置画笔颜色(淡蓝色)、宽度(2像素),用来设置矩形区域的边框。然后使用setBrush()来设置画刷颜色(橙色),用来填充矩形区域,最后调用drawRect()来实现矩形的绘制,其中参数依次顺序为x、y、w、h,是指区域从x为50,y为50的坐标点起,宽度为160,高度为100的矩形。

绘制弧线

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); // 矩形
QRectF rect(90.0, 90.0, 80.0, 90.0);
// 起始角度
int startAngle = 30 * 16;
// 跨越度数
int spanAngle = 120 * 16; QPainter painter(this); // 反走样
painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色、宽度
painter.setPen(QPen(QColor(0, 160, 230), 2)); // 绘制弧线
painter.drawArc(rect, startAngle, spanAngle);
}

画弧线时,角度被分成了十六分之一,就是说,如果要30度,就需是30*16。它有起始角度和跨度,还有位置矩形,所以,要想画出自己想要的弧线,就需要大概估算出各个参数的预估值。

绘制椭圆

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this); // 反走样
painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色、宽度
painter.setPen(QPen(QColor(0, 160, 230), 2)); // 绘制椭圆
painter.drawEllipse(QPointF(120, 60), 50, 20); // 设置画刷颜色
painter.setBrush(QColor(255, 160, 90)); // 绘制圆
painter.drawEllipse(QPointF(120, 140), 40, 40);
}

这里我们绘制了一个椭圆和一个圆形,都是调用drawEllipse接口,我们可以很轻易的发现,如果为椭圆的时候,后面两个参数不一样,圆形则相同。首先我们来看第一个参数QPointF是指椭圆的中心点相对当前窗体QPoint(0, 0)点的位置,后面的参数指椭圆的x轴及y轴的半径。

绘制多边形

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this); // 反走样
painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色
painter.setPen(QColor(0, 160, 230)); // 各个点的坐标
static const QPointF points[4] = {QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100)}; // 绘制多边形
painter.drawPolygon(points, 4);
}

首先我们顶一个个坐标点的位置,这里有四个点,分别为:QPointF(30, 40)、QPointF(60, 150)、QPointF(150, 160)、 QPointF(220, 100),然后调用drawPolygon将各个点连接起来,绘制为多边形。

绘制图片

效果

源码

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); QPainter painter(this); // 反走样
painter.setRenderHint(QPainter::Antialiasing, true); // 绘制图标
painter.drawPixmap(rect(), QPixmap(":/Images/logo"));
}

通过drawPixmap()来绘制图片,我们可以指定图片绘制的区域QRect,这里为整个界面的区域,当界面伸缩的时候,图片也会跟着伸缩。

总结

基本的文本、直线、矩形、椭圆、多边形、图片的绘制已经分享完了,还有一些细节我们没有讲解,关于其它图形的绘制也大同小异,这些我们都在后面做详细的讲解。

Qt之图形(QPainter的基本绘图)的更多相关文章

  1. QT 基本图形绘制

    QT 基本图形绘制 1.告诉绘制引擎一些东西 QPainter::Antialiasing 在可能的情况下,反锯齿       QPainter::TextAntialiasing 在可能的情况下,文 ...

  2. Qt之图形视图框架

    简述 图形视图(Graphics View)提供了一个平台,用于大量自定义2D图元的管理与交互,并提供了一个视图部件(view widget)来显示可以缩放和旋转的图元. 框架包括一个事件传播架构,支 ...

  3. Qt之图形(QPainterPath)

    简述 QPainterPath 类(绘图路径)提供了一个容器,用于绘图操作,可以创建和重用图形形状. 绘图路径是由许多图形化的构建块组成的对象,例如:矩形.椭圆.直线和曲线.构建块可以加入在封闭的子路 ...

  4. Qt之图形(组合)

    简述 使用QPainter绘制图形或者图像时,在重叠区域使用组合模式(Composition_mode).在绘图设备上通过组合模式使用QImage时,必须使用Format_ARGB32_Premult ...

  5. Qt之图形(绘制漂亮的圆弧)

    简述 综合前面对二维绘图的介绍,想必我们对一些基本绘图有了深入的了解,下面我们来实现一些漂亮的图形绘制. 简述 圆形 效果 源码 弧形 效果 源码 文本 效果 源码 旋转 效果 源码 圆形 经常地,我 ...

  6. 使用Qt 开发图形界面的软件

    3DSlicer, a free open source software for visualization and medical image computing AcetoneISO:镜像文件挂 ...

  7. 使用Qt 开发图形界面的软件(尘中远)

    3DSlicer, a free open source software for visualization and medical image computing AcetoneISO:镜像文件挂 ...

  8. Qt之图形(简笔画-绘制卡通蚂蚁)

    简述 关于简笔画的介绍很多,有动物.水果.蔬菜.交通工具等,通常会对绘制一步步进行拆分.组合.然后绘制为我们想要的结果. 下面来介绍另外的一个种类:昆虫类-卡通蚂蚁. 简述 绘制 效果 源码 绘制 效 ...

  9. Qt之图形(绘制文本)

    简述 前面我们讲解了Qt图形的基本绘制,其中包括: 绘制文本.直线.直线.矩形.弧线.椭圆.多边形.图片,以及其它一些高级用法,比如:渐变.转换等. 本节我们来详细讲解文字的绘制.主要通过QPaint ...

随机推荐

  1. HDU 6125 Free from square (状压DP+分组背包)

    题目大意:让你在1~n中选择不多于k个数(n,k<=500),保证它们的乘积不能被平方数整除.求选择的方案数 因为质数的平方在500以内的只有8个,所以我们考虑状压 先找出在n以内所有平方数小于 ...

  2. ansible组件 Ad-Hoc

    ad hoc ---临时的,在ansible里需要快速执行,并不用保存命令的执行方式 简单命令 playbook 复杂命令     EXAMPLES: - name: install the late ...

  3. crm 系统项目(三) 业务

    1. 项目背景 crm系统是某教育平台正在使用的项目,系统主要为 销售部.运营部.教质部门提供管理平台,随着公司规模的扩展,对公司员工的业务信息量化以及信息化建设越来越重要. crm系统为不同角色的用 ...

  4. VUE:内置指令与自定义指令

    VUE:内置指令与自定义指令 常用的内置指令 1)v:text 更新元素的 textContent 2)v-html 更新元素的 innerHTML 3)v-if 如果为true,当前标签才会输出到页 ...

  5. ASP.NET-HttpPostedFileBase file为null的问题

    MVC使用Ajax.BeginForm上传图片时HttpPostedFileBase file为null,Request.Files获取不到文件,问题分析是页面中存在jquery.unobtrusiv ...

  6. lambda的函数式接口

    函数式接口就是只包含一个抽象方法的接口A(不包括默认抽象方法,但包括继承来的方法):这个接口用来作为一个可变作用的方法B的参数.函数式接口的抽象方法的参数类型和返回值就是一套签名,这个签名叫做函数描述 ...

  7. 关于Android的.so文件所须要知道的

    早期的Android系统差点儿仅仅支持ARMv5的CPU架构,你知道如今它支持多少种吗?7种. Android系统眼下支持以下七种不同的CPU架构:ARMv5.ARMv7 (从2010年起),x86 ...

  8. hdu Escape

    Escape 题目: 非常裸的多重匹配. 可是点数较多,所以要用到状态压缩. . .. .. 第一次写. 好厉害的赶脚. #include <iostream> #include < ...

  9. the process android.process.acore has stopped或the process com.phone。。。。

    模拟器一启动 The process android.process.acore has stopped unexpectedly 今天不知道怎么回事,模拟器一启动就狂报错, 模拟器已经重新安装过了, ...

  10. JAVA设计模式之【策略模式】

    策略模式 定义一些独立的类来封装不同的算法 类似于common方法或者引用类 角色 环境类Context 抽象策略Strategy 具体策略ConcreteStrategy 重构伴随着设计模式 重构类 ...