【Qt绘图】—— 运用Qt进行绘图

目录

(一)基本概念

(二)绘制各种形状

2.1 绘制线段

2.2 绘制矩形 

2.3 绘制圆形 

2.4 绘制文本

2.5 设置画笔 

2.6 设置画刷 

(三)绘制图片

3.1 绘制简单图片

3.2 平移图片 

3.3 缩放图片

3.4 旋转图片

(四)其他设置

4.1 移动画家位置

4.2 保存/加载画家的状态 

(五)特殊的绘图设备 

5.1 QPixmap

5.2 QImage

5.3 QPicture


(一)基本概念

虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景.

很多时候我们需要更强的"自定制"能力.

Qt 提供了画图相关的API,可以允许我们在窗口上绘制任意的图形形状,来完成更复杂的界面设计.

  • 所谓的"控件",本质上也是通过画图的方式画上去的.
  • 画图API和控件之间的关系,可以类比成机器指令和高级语言之间的关系.
  • 控件是对画图API的进⼀步封装;画图API是控件的底层实现. 

绘图API核心类 

绘图API的使用,⼀般不会在QWidget的构造函数中使用,而是要放到paintEvent 事件中. 

关于 paintEvent

paintEvent 会在以下情况下被触发:

  • 控件首次创建.
  • 控件被遮挡,再解除遮挡. 
  • 窗口最小化,再恢复. 
  • 控件⼤小发生变化时.
  • 主动调用 repaint() 或者 ...... update() 方法.(这两个方法都是 QWidget 的方法).
  • 因此,如果把绘图api放到构造函数中调用,那么⼀旦出现上述的情况,界面的绘制效果就⽆法确保符合预期了.

(二)绘制各种形状

2.1 绘制线段

示例1:

void drawLine(const QPoint &p1, const QPoint &p2);参数:
p1:绘制起点坐标
p2:绘制终点坐标void drawLine {int x1, int y1, int x2, int y2};参数:
x1,y1:绘制起点坐标
x2,y2:绘制终点坐标

1、在"widget.h"头文件中声明绘图事件;

2、在"widget.cpp"文件中重写paintEvent()方法; 

实现效果如下: 


2.2 绘制矩形 

void QPainter::drawRect(int x, int y, int width, int height);参数:
x:窗⼝横坐标;
y:窗⼝纵坐标;
width:所绘制矩形的宽度;
height:所绘制矩形的⾼度;

示例如下:


2.3 绘制圆形 

void QPainter::drawEllipse(constQPoint &center, int rx, int ry);参数:
center:中⼼点坐标
rx:横坐标
ry:纵坐标

示例如下: 


2.4 绘制文本

QPainter类中不仅提供了绘制图形的功能,还可以使用QPainter::drawText()函数来绘制文字,也可以使用QPainter::setFont() 设置字体等信息。 

 示例如下: 

实现效果如下:


2.5 设置画笔 

 QPainter 在绘制时,是有⼀个默认的画笔的。在使用时也可以自定义画笔。在Qt中,QPen类中定义了QPainter应该如何绘制形状、线条和轮廓。同时通过QPen类可以设置画笔的线宽、颜色、样式、 画刷等。

画笔的颜⾊可以在实例化画笔对象时进行设置,画笔的宽度是通过setWidth()⽅法进行设置,画笔的风格是通过setStyle()⽅法进行设置,设置画刷主要是通过setBrush()⽅法。

  • 设置画笔颜色:QPen::QPen(constQColor&color) 画笔的颜色主要是通过QColor类设置;
  • 设置画笔宽度:voidQPen::setWidth(intwidth)
  • 设置画笔风格:voidQPen::setStyle(Qt::PenStylestyle)

画笔的风格有:


示例:画笔的使用

 实现效果如下:


2.6 设置画刷 

在Qt中,画刷是使用QBrush类来描述,画刷大多用于填充。QBrush定义了QPainter的填充模式, 具有样式、颜色、渐变以及纹理等属性。

画刷的格式中定义了填充的样式,使用Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进行任何填充。可以通过Qt助⼿查找画刷的格式。如下图示:

  • 设置画刷主要通过void QPen::setBrush(const QBrush& brush)方法,其参数为画刷的格式。 

示例如下:

实现效果:


(三)绘制图片

Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap和QPicture,它们都是常用的绘图设备。其中QImage主要用来进行I/O处理,它对I/O处理操作进行了优化,而且可以用来直接访问和操作像素;QPixmap主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;QBitmap 是QPixmap的⼦类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;QPicture用来记录并 重演QPainter命令。本期只讲解QPixmap。

3.1 绘制简单图片

 1. 新建Qt项目,基类选择QWidget,项目名称为QPainter。在"widget.h"头文件中声明绘画事 件;如下图示:

2. 添加资源文件。(⾸先准备⼀些图⽚资源文件,并将这些图⽚资源文放在同⼀个文件夹中,将该文件夹复制到本项目中) 

3. 选中项目文件,鼠标右键------->addnew... ,点击"addnew..."之后选择"Choose...",给资源文件命名,在点击"下⼀步",最后点击“完成”

4. 给资源文件添加前缀,并将资源文件添加至项目中。将所有的资源文件添加到项目中,方便后续使用。最后点击"构建并运行"按钮,将资源文件添加到项目中

5. 在"widget.cpp"文件中实现画图片功能;

实现效果如下:


3.2 平移图片 

平移图片实际是通过改变坐标来实现。QPainter类中提供了translate()函数来实现坐标原点的改变。


3.3 缩放图片

在Qt中,图片的放大和缩小可以使用QPainter类中的drawPixmap()函数来实现。 

示例如下:

实现效果如下:

 


3.4 旋转图片

图⽚的旋转使用的是QPainter类中的rotate()函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用 translate()函数完成。

示例如下:

实现效果如下: 


(四)其他设置

4.1 移动画家位置

有时候在绘制多个图形时,想使用同⼀坐标位置,那么绘制出来的图形肯定会重合,此时,可以通过移动画家的位置来使图形不发生重合。

示例1:未移动画家位置

实现效果如下:


示例2:移动画家位置 

  •  使用 translate 移动画家所在位置.

实现效果如下:


4.2 保存/加载画家的状态 

在绘制图形的过程中,可以通过save()函数来保存画家的状态,使⽤restore()函数还原画家状态。

save() 函数原型如下:

示例如下:

实现效果如下:

 说明:

  • 上述示例中,在画第三个圆之前,由于还原了画家的状态,所以此时画家的位置坐标会移动到画家状态保存的地方,所以在绘制第三个圆的位置时实际是和第⼆个圆发生了重叠。

(五)特殊的绘图设备 

前面的代码中我们是使用QWidget作为绘图设备.在Qt中还存在下列三个比较特殊的绘图设备.此处简要介绍.

  •  QPixmap用于在显示器上显示图片.
  • QImage用于对图片进行像素级修改.
  • QPicture 用于对QPainter的⼀系列操作进行存档.

5.1 QPixmap

QPixmap核心特性:

  • 使用QPainter直接在上⾯进行绘制图形.
  • 通过文件路径加载并显示图⽚.
  • 搭配QPainter的drawPixmap()函数,可以把这个图⽚绘制到⼀个QLabel、QPushButton等控件上.
  • 和系统/显示设备强相关,不同系统/显示设备下,QPixmap的显示可能会有所差别.

示例如下: 

实现效果:

 


5.2 QImage

QImage的核心特性:

  • 使用QPainter直接在上⾯进行绘制图形.
  • 通过文件路径加载并显示图⽚.
  • 能够针对图片进行像素级别的操作(操作某个指定的像素).
  • 独立于硬件的绘制系统,能够在不同系统之上提供⼀致的显示.

代码示例:QImage作为绘图设备的使用


 

5.3 QPicture

QPicture 核心特性:

  • 使用QPainter直接在上面进行绘制图形.
  • 通过文件路径加载并显示图片.
  • 能够记录QPainter的操作步骤.
  • 独力于硬件的绘制系统,能够在不同系统之上提供⼀致的显示

注意: QPicture 加载的必须是自身的存档⽂件,而不能是任意的png,jpg等图片文件.

QPicture类似于很多游戏的Replay功能.

例如像war3这样的经典游戏,即使是⼀场60分钟的膀胱局,生成的replay文件,也不过几百个KB.

此处的Replay功能并非是把整个游戏画面都录制保存下来,而是记录了地图中发生的所有事 件(地图元素,玩家单位操作,中立生物行为等...). 

当回放Replay的时候其实就是把上述记录的事件再⼀条⼀条的执行⼀遍即可还原之前的游戏 场景了.

如果要记录下QPainter的命令,⾸先要使⽤QPainter::begin()函数,将QPicture实例作为参数传递 进去,以便告诉系统开始记录,记录完毕后使用QPainter::end()命令终⽌。如下示例:

实现效果:

通过QPicture重现绘图指令后,实现的效果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1535730.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

TCP客户端编码和解码处理:发送和接收指定编码消息

文章目录 引言基于Netty实现TCP客户端Netty发送GBK编码指令Netty接收GBK编码基于Channel发送指令基于ChannelHandlerContext发送指令:建立连接时发送登陆指令开启日志,查看报文信息基于ChannelInboundHandlerAdapter进行业务逻辑处理原生API实现TCP客户端基于DataOutputStrea…

C++入门 之 类和对象(上)

目录 一、类的定义 1.类定义格式 2.访问限定符 3.类域 二、实例化 1.实例化概念 2.对象大小 3.this指针 一、类的定义 1.类定义格式 1、class Stack{};class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义…

Vue3.0组合式API:computed计算属性、watch监听器、watchEffect高级监听器

1、computed() 计算属性 在模板中绑定表达式只能用于简单的运算。如果运算比较复杂,可以使用 Vue.js 提供的计算属性,通过计算属性可以处理比较复杂的逻辑。 1.1 计算属性的应用 通过计算属性可以实现各种复杂的逻辑,包括运算、函数调用等…

【自然语言处理】实验三:新冠病毒的FAQ问答系统

目录 前言 1.新建data_process.py 1.1导入包并定义功能模块1用来读取问题和答案FAQ的文件 1.2功能模块2:进行问题/问题列表处理(正则化,分词) 1.3功能模块3:处理输入的问题 1.4功能模块4:计算输入问题与问题…

Python | Leetcode Python题解之第405题数字转换为十六进制数

题目: 题解: CONV "0123456789abcdef" class Solution:def toHex(self, num: int) -> str:ans []# 32位2进制数,转换成16进制 -> 4个一组,一共八组for _ in range(8):ans.append(num%16)num // 16if not num:b…

Python实用的27个实例,涵盖从基础到进阶的所有领域!

Python 是一种广泛使用的高级编程语言,以其简洁的语法和丰富的库支持而受到开发者们的喜爱。以下列出了 27 个实用的 Python 实例,涵盖从基础到进阶的不同领域,帮助你提升编程技能。 1. 打印 "Hello, World!" print("Hello,…

预训练发展

预训练发展 1.ELMo2.GPT3.Bert3.1Ernie-baidu3.2Ernie- Tsinghua 4.GPT25.UNILM6.Transformer-XL & XLNet6.1方案一6.2方案三 7.Roberta8.SpanBert8.1SBO简介: 9.ALBERT9.1方案一9.2方案二9.3方案三 10.T511.GPT312.从"续写"到"回答"12.1SF…

可解释性机器学习中的局部解释

可解释性机器学习可以被分成两大类,第一大类叫做局部的解释,第二大类叫做全局的 解释,如图 1 所示。局部的解释是,比如有一个图像分类器,输入一张图片,它会判断出 是一只猫,机器要回答问题是为什…

浅谈Spring Cloud:认识微服务

SpringCloud就是分布式微服务架构的一站式解决方案,是微服务架构落地的多种技术的集合。 目录 微服务远程调用 Eureka注册中心 搭建Eureka Server 注册组件 服务拉取 当各种各样的服务越来越多,拆分的也越来越细,此时就会出现一个服务集…

速通GPT:《Improving Language Understanding by Generative Pre-Training》全文解读

文章目录 速通GPT系列几个重要概念1、微调的具体做法2、任务感知输入变换3、判别式训练模型 Abstract概括分析和观点1. 自然语言理解中的数据问题2. 生成预训练和监督微调的结合3. 任务感知输入变换4. 模型的强大性能 Introduction概括分析和观点1. 自然语言理解的挑战在于对标…

Android源码导入Android Studio

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 前言 需要先把 Android 源码编译一遍 然后执行下面指令就可以导入android源码了 关于 Android 源码编译可以参考这篇文章【LineageOS源码下载和编译&#xf…

【检索快,IEEE独立出版】2024年第四届电子信息工程与计算机科学国际会议(EIECS 2024)

大会简介: 2024年第四届电子信息工程与计算机科学国际会议(EIECS 2024)将于2024年9月27日至29日在中国延吉举行。会议由长春理工大学主办,延边大学、长春理工大学电子信息工程学院、长春理工大学计算机科学技术学院、长春理工大学…

蛋白质原子坐标平移、旋转、缩放示例代码

在处理蛋白质结构时,常常需要对原子的坐标进行几何变换,如平移、旋转和缩放。这些变换在模拟、可视化和结构比较中非常有用。 以下是对这些操作的介绍以及示例代码。 1. 平移 (Translation) 平移就是将所有原子的坐标沿着某个方向进行移动。平移可以通过向每个原子的坐标加…

解锁4款专业的中英翻译工具,让你畅行双语世界。

中英翻译工具在国际化交流越来越频繁的今天还是起着巨大的作用的,它能够促进很多知识的传播和共享,也能够便利大家的工作,学习和生活。今天我就要跟大家分享4个我一直都在用的中英翻译工具。 1、福昕中英翻译网站 直达:https://f…

LeetCode 第415场周赛个人题解

目录 Q1. 数字小镇中的捣蛋鬼 原题链接 思路分析 AC代码 Q2. 最高乘法得分 原题链接 思路分析 AC代码 Q3. 形成目标字符串需要的最少字符串数 I 原题链接 思路分析 AC代码 Q4. 形成目标字符串需要的最少字符串数 II 原题链接 思路分析 AC代码 Q1. 数字小镇中的捣…

数据库全攻略:从类型到安全与优化

数据库全攻略:从类型到安全与优化 一、数据库类型大观 (一)关系型数据库 关系型数据库以表格形式存储数据,通过 SQL 语言进行操作,数据之间存在关联关系,适合复杂查询和事务处理。常见的关系型数据库有 …

springboot瑜伽课约课小程序-计算机毕业设计源码87936

摘要 本文详细阐述了一个基于SpringBoot框架的瑜伽课约课小程序的设计与实现过程。随着现代生活节奏的加快,越来越多的人开始关注身心健康,瑜伽作为一种集健身、放松、减压于一体的运动方式,受到了广泛的欢迎。为满足瑜伽爱好者的课程预约和学…

Ubuntu 22.04.5 LTS 发布下载 - 现代化的企业与开源 Linux

Ubuntu 22.04.5 LTS (Jammy Jellyfish) - 现代化的企业与开源 Linux Ubuntu 22.04.5 发布,配备 Linux 内核 6.8 请访问原文链接:https://sysin.org/blog/ubuntu-2204/,查看最新版。原创作品,转载请保留出处。 作者主页&#xf…

Recyclerview实现滑动居中缩放菜单

最近项目中需要的一个滑动菜单效果:要求当前居中选项放大、滑动时有缩放效果、点击两边的选项滑动到屏幕中央、停止滑动选项停留在屏幕中间(类似viewPager的效果),为了直观,先上最终实现效果图: 大体思路: Recyclerview item头尾添加空数据,让第一个和最后一个item也能…

c++题目_【模板】最小生成树Prim

题目描述 这是一道最小生成树Prim的模板题,本题与【模板】最小生成树Kruskal,仅仅只有nn和mm的大小不同 给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入 第一行输入2个正整数n,mn,m,代表…