【Qt】绘图与绘图设备

文章目录

  • 绘图设备
  • QPainter绘图实例
    • 案例1
    • 案例2-高级设置
    • 案例3:利用画家画资源图片 点击按钮移动图片
  • QtPaintDevice实例
    • Pixmap绘图设备
    • QImage 绘图设备
    • QPicture 绘图设备

QPainter绘图

Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类

  • QPainter用来执行绘制的操作
  • QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间
  • QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的

可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔

层次结构

img

**Qt 的绘图系统实际上是,使用QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter的指令)


绘图设备

绘图设备是指继承QPainterDevice的子类,Qt一共提供了四个这样的类:QPixmap、QBitmap、QImage和 QPicture

  • QPixmap专门为图像在屏幕上的显示做了优化
  • QBitmap是QPixmap的一个子类,它的色深限定为1,可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap,因为QBitmap色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。
  • QImage专门为图像的像素级访问做了优化
  • QPicture则可以记录和重现QPainter的各条命令。 QPicture将QPainter的命令序列化到一个IO设备,保存为一个平台独立的文件格式

QPainter绘图实例

案例1

首先需要在Widget文件当中重写绘图事件:

image-20231005155422449


void MainWindow::paintEvent(QPaintEvent *)
{//实例化画家对象  this指定的是绘图设备 在当前窗口画画QPainter painter(this);//设置画笔QPen pen(QColor(255,0,0)); //RGB  目前是红笔//设置画笔宽度pen.setWidth(3);    //设置画笔风格pen.setStyle(Qt::DotLine);//让画家 使用这个笔painter.setPen(pen);//设置画刷=》对于封闭的图形内部会上色  Qt::cyan  Qt::green 也可以...QBrush brush(Qt::cyan); //QBrush brush(QColor(255,0,0)) 也可以//设置画刷风格brush.setStyle(Qt::Dense7Pattern);//让画家使用画刷painter.setBrush(brush);//画线 =>两点确定一线painter.drawLine(QPoint(0,0) , QPoint(100,100));//画圆 椭圆  ⚪也是椭圆的一种painter.drawEllipse( QPoint(100,100) , 50,50); //参数依次代表:圆心 左半径  上半径//画矩形painter.drawRect(QRect(20,20,50,50));//参数依次代表:左上角的点 宽 高//画文字 =>本质是在矩形框内部画文字painter.drawText(QRect(10,200,150,50) , "好好学习,天天向上");
}
image-20231005155857200

案例2-高级设置

QPainter painter(this);
painter.drawEllipse(QPoint(100,50) , 50,50); //画圆//设置 抗锯齿能力=>画的更好  但是效率较低
painter.setRenderHint(QPainter::Antialiasing);
painter.drawEllipse(QPoint(200,50) , 50,50);//画圆// 画图1->保存点->画图2->恢复到保存点->画图3  所以最后只有画图1和3的矩形
painter.drawRect(QRect(20,20,50,50));//移动画家位置开始画画的位置
painter.translate(100,0);//保存画家状态
painter.save();painter.drawRect(QRect(20,20,50,50));painter.translate(100,0);//移动画家位置开始画画的位置//还原画家保存状态 =>在这里的代码当中,只打印了两个矩形,有一个被覆盖了
painter.restore();painter.drawRect(QRect(20,20,50,50));

image-20231005160220261


案例3:利用画家画资源图片 点击按钮移动图片

前置工作:

1.在ui界面当中新增加一个按钮:移动图片

2.在mainWidget.h当中新增一个成员:int posX = 0

3.引入资源文件

构造函数

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//点击移动按钮,移动图片connect(ui->pushButton,&QPushButton::clicked,[=](){posX+=20;//如果要手动调用绘图事件 用update更新update();//更新绘图事件});//开启定时器QTimer * timer = new QTimer(this);timer->start(10);connect(timer,&QTimer::timeout,[=](){posX++;update();//更新绘图事件});}
void MainWindow::paintEvent(QPaintEvent *)
{/利用画家 画资源图片 ///QPainter painter(this); //画在当前窗口QPixmap pix = QPixmap(":/image/tree.png");//如果超出屏幕,重新从0位置开始往右移动if(posX >= this->width()) //this->width()屏幕的宽度  this->height()屏幕的高度{posX = 0;}painter.drawPixmap(posX,0,pix); //posX:类的成员
}

QtPaintDevice实例

同理也需要重写绘图事件

//绘图事件
void paintEvent(QPaintEvent *);

Pixmap绘图设备

//Pixmap绘图设备 会专门为平台做了显示的优化
QPixmap pix(300,300);//相当于300*300的宽 高的纸张//填充背景颜色
pix.fill(Qt::white);//声明画家
QPainter painter(&pix);//往pix当中画画painter.setPen(QPen(Qt::green));//设置画笔颜色
painter.drawEllipse(QPoint(150,150) , 100,100);//画圆//保存到磁盘的某个位置
pix.save("E:\\pix.png");

QImage 绘图设备

实例1

QImage img(300,300,QImage::Format_RGB32); //宽 高
img.fill(Qt::white);QPainter painter(&img);
painter.setPen(QPen(Qt::blue));
painter.drawEllipse(QPoint(150,150) , 100,100);//保存
img.save("E:\\img.png");

可以对像素进行访问

void MainWindow::paintEvent(QPaintEvent *)
{QPainter painter(this);//利用QImage 对像素进行修改QImage img;img.load("E:/img.png"); //加载图片//修改像素点for(int i = 50 ;i < 100 ; i++){for(int j = 50 ; j < 100;j++){QRgb value = qRgb(255,0,0); //像素点类型img.setPixel(i,j,value);//第i行第j列变为value该像素}}painter.drawImage(0,0,img);
}

image-20231005202013208


QPicture 绘图设备

//QPicture 绘图设备  可以记录和重现 绘图指令
QPicture pic;
QPainter painter; //可以后面再指定绘图设备
painter.begin(&pic);  //=>指定绘图设备=>开始往pic上画
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(150,150) , 100,100);
painter.end(); //结束画画//保存到磁盘
pic.save("E:\\pic.zt"); //名称和后缀名任意

然后可以在绘图事件当中进行重现:

void MainWindow::paintEvent(QPaintEvent *)
{//重现QPicture的绘图指令QPainter painter(this);QPicture pic;pic.load("E:\\pic.zt");//加载上述保存的图片的路径painter.drawPicture(0,0,pic);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apifox创建团队 项目 接口 邀请成员步骤演示

我们打开Apifox 找到 个人空间 然后 点击新建团队 然后这里 我们输入名字 点击确定 我们的团队就出来了 然后 我们点击新建项目 然后肯定是 http 项目名称输入一下 然后 语言 我们中国肯定是中文的 然后点击确定 建好之后 我们就会进入自己的项目啦 然后 我们可以新建个接…

ThinkPHP8学习笔记

ThinkPHP8官方文档地址&#xff1a;ThinkPHP官方手册 一、composer换源 1、查看 composer 配置的命令composer config -g -l 2、禁用默认源镜像命令composer config -g secure-http false 3、修改为阿里云镜像源composer config -g repo.packagist composer https://mirror…

C51--单片机中断

51单片机是单线程模式&#xff0c;需要用到硬件中断。 一、中断系统 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理器CPU正在处理某件事的时候&#xff0c;外界发生了紧急事件请求&#xff0c;要求CPU暂停当前工作&#xff0c;转而去处理这个紧急…

程序员们平时都喜欢逛什么论坛呢?

网站不在多&#xff0c;好用就行&#xff1b;技术不求精&#xff0c;好摸鱼就行。是时候祭出我收藏夹里的这15个网站了&#xff01; 求职必备&#xff1a;牛客网 https://www.nowcoder.com/ 年少不知牛客好&#xff0c;等到要面试的时候才发现是神器。 你可以在牛客上搜索到一…

C#WPFPrism框架导航应用实例

本文实例演示C#WPFPrism框架导航应用实例。 一、导航实现步骤 首先创建WPF项目,修改App相关文件内容,以便使用prism。 承接上一个模块化的实例,在这个基础上更改增加导航功能。 1.1首先在ModuleA中添加ViewModels文件夹,添加ViewAViewModel.cs类 如果想上下文自动查找…

ArcGIS中批量mxd高版本转低版本

我们经常在给别人发ArcGIS的工程文件mxd&#xff0c;结果到别人那发现mxd工程文件打不开&#xff0c;原因是我们的arcgis版本高于别人&#xff0c;此时工程文件又很多&#xff0c;一个个转存成低版本又嫌麻烦&#xff0c;于是我们做了个批量mxd高版本转低版本的小工具&#xff…

论文解读:Large Language Models as Analogical Reasoners

一、动机 大模型在各种类型的NLP任务上均展现出惊艳的表现。基于CoT propmt能够更好地激发大模型解决复杂推理问题的能力&#xff0c;例如解决数学解题&#xff0c;可以让模型生成reasoning path。现有的经典的CoT方法有few-shot cot、zero-shot cot等。然后现有的cot面临两个…

Transformer模型 | 用于目标检测的视觉Transformers训练策略

基于视觉的Transformer在预测准确的3D边界盒方面在自动驾驶感知模块中显示出巨大的应用,因为它具有强大的建模视觉特征之间远程依赖关系的能力。然而,最初为语言模型设计的变形金刚主要关注的是性能准确性,而不是推理时间预算。对于像自动驾驶这样的安全关键系统,车载计算机…

C++内存管理:其七、标准库中的allocator

首先明确一点&#xff0c;绝大多数情况下&#xff0c;是标准库中的容器使用allocator。因为容器需要频繁的申请和释放内存。 一、容器使用allocator 典型的例子&#xff1a; vector<int , allocator<int>> a;但是为什么我们通常的定义vector变量的方法是&#x…

Hadoop3.0大数据处理学习1(Haddop介绍、部署、Hive部署)

Hadoop3.0快速入门 学习步骤&#xff1a; 三大组件的基本理论和实际操作Hadoop3的使用&#xff0c;实际开发流程结合具体问题&#xff0c;提供排查思路 开发技术栈&#xff1a; Linux基础操作、Sehll脚本基础JavaSE、Idea操作MySQL Hadoop简介 Hadoop是一个适合海量数据存…

Vue响应式原理和本质 | 实现一个完善的响应式系统

文章目录 前言响应式响应式的本质基本实现和工作原理完善的响应式 前言 本篇文章代码思路来自Vue3.0源码, 部分理解来源于霍春阳 《Vue.js设计与实现》这本书的理解, 感兴趣的小伙伴可以自行购买阅读。可以非常明确的感受到作者对 Vue 的深刻理解以及用心, 富含非常全面的 Vue …

Linux进程终止

文章目录 进程退出场景进程退出码strerrorerrno浅谈进程异常exit && _exit 进程退出场景 代码运行完毕&#xff0c;结果正确代码运行完毕&#xff0c;结果不正确代码异常 进程退出码 我们写的C/C的代码&#xff0c;main函数每次都需要返回0&#xff0c;而这个return…

C++:类的默认成员函数------拷贝构造函数赋值运算符重载

目录 一、前言 二、拷贝构造函数 &#x1f4a6;拷贝构造函数概念 &#x1f4a6;拷贝构造函数特性 &#x1f34e; 解释特性2&#xff1a;拷贝构造函数的参数只有一个且必须使用引用传参&#xff0c;使用传值方式会引发无穷递归调用 &#x1f350;解释特性3&#xff1a;…

Spring注解RequestBody与RequestParam详解

要注意的问题&#xff1a; RequestBody 前端的请求方法要使用post方式来进行提交&#xff1b;一个请求只能有一个RequestBody&#xff0c;也就是说&#xff0c;当一个方法中有两个参数的时候&#xff0c;最多只能有一个参数加RequestBody注解用来接受request body中的参数&am…

Qt之自定义QStringListModel设置背景色和前景色

一.效果 二.实现 QStringListModel里只实现了Qt::EditRole和Qt::DisplayRole,不能直接设置背景色和前景色,所以我们要继承QStringListModel,重写其中的data和setData方法,使其支持Qt::ForegroundRole和Qt::BackgroundRole。 QHStringListModel.h #ifndef QHSTRINGLISTMO…

Java集成支付宝支付流程

在这篇博客中&#xff0c;我们将详细介绍如何在Java应用中集成支付宝支付。我们将从支付宝支付的基本概念开始&#xff0c;然后讲解如何在Java中使用支付宝的SDK进行支付操作&#xff0c;最后我们将通过一个具体的例子来演示整个过程。 1. 支付宝支付简介 支付宝是中国最大的…

P1966 [NOIP2013 提高组] 火柴排队

洛谷的一道原题&#xff0c;方法有很多&#xff0c;树状数组以及排序&#xff0c;对刚学树状数组的人来说用排序会比较好理解。 本题最重要的结论就是&#xff0c;要保证两个数组中相同位置的差最小&#xff0c;但是不一定两个数组中数值相同&#xff0c;所以只需要保证相同位…

ChatGPT/GPT4科研技术与AI绘图及论文高效写作

2023年我们进入了AI2.0时代。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车&#xff0c;就有可能被淘汰在这个数字化时代&#xff0c;如何能高效地处理文本、文献查阅、PPT…

C语言每日一题(20)最大公因数等于 K 的子数组数目

力扣 2447 最大公因数等于 K 的子数组数目 题目描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 nums 的子数组中元素的最大公因数等于 k 的子数组数目。 子数组 是数组中一个连续的非空序列。 数组的最大公因数 是能整除数组中所有元素的最大整数。 …

王道p40 1.设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点(c语言代码实现)图解递归

视频讲解(献丑了)&#xff1a;p40 第1题 王道数据结构课后代码题c语言代码实现_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Xa4y1Q7ui/?spm_id_from333.999.0.0 首先它是一个不带头结点的单链表 我们就得特殊处理 我们先让*LNULL&#xff1b; 然后为s开辟一个新…