【Qt】绘图与绘图设备

news2024/11/15 17:44:56

文章目录

  • 绘图设备
  • 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.coloradmin.cn/o/1133747.html

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

相关文章

外卖跑腿小程序开发如何满足不断变化的用户需求?

外卖跑腿小程序市场竞争激烈&#xff0c;用户需求不断演变。为了保持竞争力&#xff0c;开发团队需要不断适应变化&#xff0c;提供新功能和改进用户体验。本文将讨论如何通过技术手段来满足不断变化的用户需求。 1. 灵活的后端服务 后端服务是外卖跑腿小程序的核心&#xf…

Sui主网升级至V1.12.2版本

其他升级要点如下所示&#xff1a; #14305 使Sui能够验证zkLogin历史地址&#xff08;通过已填充的address_seed派生&#xff09;。升级协议版本至29&#xff0c;以启用对历史地址的验证。 #14100 修复了verify_zklogin_id函数中的错误&#xff0c;该函数按预期返回一个Ver…

Flutter extended_image库设置内存缓存区大小与缓存图片数

ExtendedImage ExtendedImage 是一个Flutter库&#xff0c;用于提供高级图片加载和显示功能。这个库使用了 image 包来进行图片的加载和缓存。如果你想修改缓存大小&#xff0c;你可以通过修改ImageCache的配置来实现。 1. 获取ImageCache实例: 你可以通过PaintingBinding…

Ansible简介

环境 控制节点&#xff1a;Ubuntu 22.04Ansible 2.10.8管理节点&#xff1a;CentOS 8 组成 Ansible环境主要由三部分组成&#xff1a; 控制节点&#xff08;Control node&#xff09;&#xff1a;安装Ansible的节点&#xff0c;在此节点上运行Ansible命令管理节点&#xff…

【剑指Offer】38.字符串的排列

题目 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数据范围&#xff1a;n<10 要求&#xff1a;空间复…

基于springboot实现篮球竞赛预约平台管理系统项目【项目源码+论文说明】

基于springboot实现篮球竞赛预约平台管理系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;篮球竞赛预约平台也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&…

【图解数据结构】手把手教你如何实现顺序表(超详细)

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、算法模板、汇编语言 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️线性表1.1 &#x1f514;线性表的定义1.2 &#x1f514;线性表的存储结构 二. ⛳️…

JavaScript进阶 第三天笔记

JavaScript 进阶 - 第3天笔记 了解构造函数原型对象的语法特征&#xff0c;掌握 JavaScript 中面向对象编程的实现方式&#xff0c;基于面向对象编程思想实现 DOM 操作的封装。 了解面向对象编程的一般特征掌握基于构造函数原型对象的逻辑封装掌握基于原型对象实现的继承理解什…

对比Vue2和Vue3的自定义指令

一、自定义指令简介 自定义指令是Vue提供的能力,用于注册自定义的指令,从而实现一些自定义的DOM操作。 二、Vue2中自定义指令 在Vue2中,自定义指令通过全局方法Vue.directive()进行注册: // 注册全局指令v-focus Vue.directive(focus, {inserted: function(el) {el.focus()…

短视频矩阵剪辑分发+AI无人直播的如何开发技术搭建?

搭建步骤&#xff1a; 1. 首先需要根据自身产品确定视频类型及需要实现的视频效果 2. 根据预期视频效果选择视频上传模式&#xff0c;并将视频素材进行上传 3. 添加音频、字幕&#xff0c;标题等与素材进行组合。 4. 设置投放计划&#xff0c;包括&#xff1a;视频标题、视频…

如何解决找不到xinput1_3.dll无法继续执行此代码?5个解决方法分享

由于各种原因&#xff0c;电脑可能会出现一些问题&#xff0c;其中之一就是电脑提示找不到xinput1_3.dll。这个问题可能会导致一些应用程序无法正常运行&#xff0c;给用户带来困扰。那么&#xff0c;当遇到这个问题时&#xff0c;我们应该如何修复呢&#xff1f;小编将详细介绍…

C语言 每日一题 PTA 10.25 day4

10.25 求解马鞍点问题 若矩阵Anm中某个元素A[i][j]是矩阵第i行中值最小的元素&#xff0c;同时又是第j列中值最大的元素&#xff0c;则称元素A[i][j]是矩阵中的一个马鞍点。 设以二维数组存储矩阵&#xff0c;编写算法求矩阵A中的所有马鞍点&#xff0c;算法的时间复杂度要尽量…

【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《系统工程与信息系统基础》

本篇文章主要分享软考中系统工程与信息系统基础章节相关知识点。 系统工程与信息系统基础 [01] 霍尔三维结构以时间维、逻辑维、&#xff08;&#xff09;维组成的立体结构概括性地表示出系统工程的各阶段、各步骤以及所涉及的知识范围。其中时间维是系统的工作进程&#xff0…

OSATE 插件 Cheddar 的安装与简单使用

一、Cheddar简介 Cheddar是一个开源的实时系统任务调度模拟器/分析仪&#xff0c;可以使用Cheddar进行任务的可调度性分析以及相关的性能分析。对于Cheddar的详细信息可以参考其官网&#xff1a; Cheddar - open-source real-time scheduling simulator/analyzer (univ-brest…

JS加密/解密之手搓进阶版加密

前言 以前给大家介绍过一个简单的加密原理&#xff0c;是通过将字符串转换储层ascii码进行加密处理&#xff0c;这次介绍一个进阶版。解密难度直接上升了好几倍&#xff0c;加密代码放在下方各位自己尝试&#xff0c;解密代码就不贴了&#xff0c;感兴趣的可以到我的js加密官网…

Echarts的legend的特殊图例展示

问题描述 如图的红框中(上图是设计稿)&#xff0c;默认总发行和总到期都是矩形&#xff0c;即默认的情况下图例是25*14的&#xff0c;但是设计稿要求前两世正方形的。 问题复现&#xff1a; 默认的情况下&#xff0c;柱状图的图例是矩形(长方形),不是设计稿中的正方形。 演示…

什么是空运特殊货物_箱讯科技国际物流管理平台

空运货物具有时效快、安全性高等优势特点&#xff0c;但空运也有一定限制性。当然无论任何运输方式&#xff0c;运输对象都有这样的分类&#xff1a;普通货物、特殊货物。 那么在国际空运中&#xff0c;特殊货物是指什么呢&#xff1f; 01空运特殊货物 空运特殊货物是指那些无…

【网络协议】聊聊TCP的三挥四握

上一篇我们说了网络其实是不稳定的&#xff0c;TCP和UDP其实是两个不同的对立者&#xff0c;所以TCP为了保证数据在网络中传输的可靠性&#xff0c;从丢包、乱序、重传、拥塞等场景有自己的一套打法。 TCP格式 源端口和目标端口是不可缺少的&#xff0c;用以区分到达发送给拿…

生产环境元空间内存溢出(OOM)的问题排查

一、现象 2023.10.17下午收到业务反馈&#xff0c;说是接口调用超时&#xff0c;进件系统和核心系统调用外数系统接口时等待过久&#xff0c;引起系统异常。然后我们看了下接口调用的日志&#xff0c;确实接口的响应时间在五十秒左右。我们自己测试了下&#xff0c;发现也是这…