【QT学习】9.绘图,三种贴图,贴图的转换,不规则贴图(透明泡泡)

一。绘图的解释

        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()。

补充:绘图可看成画板,画布,画家,画笔,画刷组成。


————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/liang19890820/article/details/51154216

二。绘图具体功能演示

1.绘图事件paintEvent(QPaintEvent *event)

1.添加头文件

#include <QPainter>
#include <QPaintEvent>

2.绘图事件函数

void Widget::paintEvent(QPaintEvent *event){
    static int n=0;
    qDebug()<<n++<<endl;
}

结果:

        1.拖动窗口:不触发事件

        2.放大缩小窗口:触发事件

        3.隐藏显示窗口:触发事件

用此事件刷新页面。

2.使用QPainter绘图(使用画笔Qpen)

1.绘图步骤

//此函数响应后,用来刷新页面
void Widget::paintEvent(QPaintEvent *event){
    //画家
    QPainter p;//制作画家对象
    p.begin(this);//画家在画板上画画(指定画在什么上)
    //画笔
    QPen pen;
    pen.setColor(Qt::red);//红色
    pen.setWidth(5);//宽度
    pen.setStyle(Qt::SolidLine);//实线
    //画笔交给画家
    p.setPen(pen);
    //画家画画
    p.drawRect(0,0,100,100);//画长方形
    //----------------------------------------
    //重新设置画笔
    pen.setColor(Qt::green);//设置画笔
    pen.setWidth(3);
    pen.setStyle(Qt::DotLine);
    p.setPen(pen);//画笔交给画家
    p.drawEllipse(150,150,100,100);//画椭圆
    //画完了
    p.end();
}

2.使用QPainter创建画家,给他材料去画画

2.使用QPainter绘图(使用画刷QBrush)

1.QPainter调用QBrush画画

//此函数响应后,用来刷新页面
void Widget::paintEvent(QPaintEvent *event){
    //画家
    QPainter p;//制作画家对象
    p.begin(this);//画家在画板上画画(指定画在什么上)
    //制作画刷
    QBrush brush;
    brush.setColor(QColor(0,255,255));
    brush.setStyle(Qt::Dense1Pattern);
    p.setBrush(brush);
    p.drawRect(200,100,100,100);
    //画完了
    p.end();
}

三。贴图

贴图:

  1. QBitmap 和 QPixmap

                QBitmap :黑白色

                QPixmap :彩色

2. QPixmap QImage Qpicture

  1. QPixmap 适应不同平台 不能改 保存成各种各样的格式的图片文件
  2. QImage  不适应平台   可以修改内容   保存成各种各样的格式的图片文件
  3. QPicture  保存成二进制文件

1.彩图,黑白图,动图

1.创建时间事件timerEvent与绘图事件paintEvent

代码:
 

protected:
    void paintEvent(QPaintEvent *event);
    void timerEvent(QTimerEvent* e);
private:
    Ui::Widget *ui;
    int x,y;
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    x=0;y=400;
    startTimer(100);
}
void Widget::timerEvent(QTimerEvent* e){
    x += 3;
    /*this->*/update();//当前控件产生重绘事件   paintEvent
}
//此函数响应后,用来刷新页面
void Widget::paintEvent(QPaintEvent *event){
    QPainter p(this);
    p.drawPixmap(0,0,100,100,QPixmap("../0.png"));
    //p.drawPixmap(0,0,100,100,QBitmap("../0.png"));
    //p.drawPixmap(x,y,100,100,QPixmap("../0.png"));
}

2.QImage可以修改图片

1.使用QPainter画家画Qimage图,并且在上面画一些点

{
    ui->setupUi(this);
    QImage image(400,400,QImage::Format_ARGB32);
    QPainter p(&image);//QPainter p;  p.begin(&image);   p.end();

    p.drawImage(0,0,QImage("../0.png"));
    //QImage可以修改图
    QPen pen;
    pen.setColor(Qt::blue);
    p.setPen(pen);
    for(int i=0;i<20;i++){
        for(int j=0;j<20;j++){
            p.drawPoint(j,i);
        }
    }
    //保存
    image.save("../iamge0.png");
}

2.

3.QPicture保存图片为二进制文件

    QPicture picture;
    QPainter p;
    p.begin(&picture);
//等价
    /*
        QPainter p(&picture);
    */

1.代码

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPicture picture;
    picture.save("../picture0.png");
}
void Widget::paintEvent(QPaintEvent *event){
    qDebug()<<"活着"<<endl;
    QPainter p(this);
    //贴 picture类型图片
    QPicture pic;

    pic.load("../picture0.png");
    p.drawPixmap(100,100,100,100,QPixmap("../0.png"));
    p.drawPicture(0,0,pic);
}

保存成功

错误:picture图片没有显示

四。贴图的转换

    //pixmap 类型 和 image类型切换
     QPixmap pixmap;
     pixmap.load("../pixmapPaopao.png"); 
     QImage imgTemp = pixmap.toImage();
     p.drawImage(0,0,imgTemp);
 
     QImage  image;
     image.load("../iamgePaopao.png");
     p.drawPixmap(400,400,QPixmap::fromImage(image));

五。不规则贴图

1.结果:

2.步骤

创建事件,鼠标按下事件,鼠标移动事件,绘图事件。创建一个点属性。

protected:
    void paintEvent(QPaintEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
private:
    Ui::Widget *ui;
    QPoint pos;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint | windowFlags());//去掉边框
    //设置窗口背景透明
    setAttribute(Qt::WA_TranslucentBackground);
}
void Widget::mousePressEvent(QMouseEvent *event){
    if(event->button() == Qt::LeftButton){
        //     鼠标坐标           -        窗口左上角的点的坐标
        pos = event->globalPos() - this->frameGeometry().topLeft();
    }else if(event->button() == Qt::RightButton){
        //右键按下,关闭
        close();
    }
}
void Widget::mouseMoveEvent(QMouseEvent *event){
    if(event->buttons() & Qt::LeftButton){
        move(event->globalPos() - pos);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux18:进程等待

进程等待的必要性 1&#xff1a;子进程创建的目的是要完成父进程指派的某个任务&#xff0c;当子进程运行完毕退出时&#xff0c;父进程需要通过进程等待的方式&#xff0c;回收子进程资源&#xff0c;获取子进程退出信息&#xff08;子进程有无异常&#xff1f;没有异常结果是…

研究发现:提示中加入数百个示例显著提升大型语言模型的性能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

人工智能时代的关键技术:深入探索向量数据库及其在AI中的应用

文章目录 1. 理解向量数据库&#xff1a;二维模型示例2. 向量数据库中的数据存储与检索3. 向量数据库如何工作&#xff1f;4. 向量数据库如何知道哪些向量相似&#xff1f; 在人工智能技术日益成熟的当下&#xff0c;向量数据库作为处理和检索高维数据的关键工具&#xff0c;对…

LlamaIndex 加 Ollama 实现 Agent

AI Agent 是 AIGC 落地实现的场景之一&#xff0c;与 RAG 不同&#xff0c;RAG 是对数据的扩充&#xff0c;是模型可以学习到新数据或者本地私有数据。AI Agent 是自己推理&#xff0c;自己做&#xff0c;例如你对 AI Agent 说我要知道今天上海的天气怎么样&#xff0c;由于 AI…

WSL2无法ping通本地主机ip的解决办法

刚装完WSL2的Ubuntu子系统时&#xff0c;可能无法ping通本地主机的ip&#xff1a; WSL2系统ip&#xff1a; 本地主机ip&#xff1a; 在powershell里输入如下的命令&#xff1a; New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias &quo…

AI大模型探索之路-认知篇4:大语言模型预训练基础认知

文章目录 前言一、预训练流程分析二、预训练两大挑战三、预训练网络通信四、预训练数据并行五、预训练模型并行六、预训练3D并行七、预训练代码示例总结 前言 在人工智能的宏伟蓝图中&#xff0c;大语言模型&#xff08;LLM&#xff09;的预训练是构筑智慧之塔的基石。预训练过…

【简单讲解下如何学习C++】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

微信小程序开发工具的使用,各个配置文件详解,小程序开发快速入门

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

网页信息提取能力哪家强?GPT4、Claude、perplexity、kimi、通义千问大比拼

barnesandnoble网上书店有一个页面&#xff1a;https://www.barnesandnoble.com/b/books/step-into-reading-early-readers-kids-fiction/step-into-reading-book-series-a-step-3-book-childrens-fiction/_/N-29Z8q8Z2i94?Nrpp40&page1 &#xff0c; 现在想把网页上的书名…

【Linux高性能服务器编程】两种高性能并发模式剖析——半同步/半异步模式

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之两种高性能并发模式介绍&#xff0c;在这篇文章中&#xff0c;你将会学习到高效的创建自己的高性能服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家来理解…

分布式与一致性协议之拜占庭将军问题(三)

拜占庭将军问题 叛将先发送消息 如果是叛将楚先发送作战消息&#xff0c;干扰作战计划&#xff0c;结果会有所不同吗&#xff1f; 在第一轮作战信息协商中&#xff0c;楚向苏秦发送作战指令"进攻",向齐、燕发送作战指令"撤退"&#xff0c;如图所示(当然还…

【勒索病毒恢复】.svh勒索病毒介绍及恢复方案

一、.[[backupwaifu.club]].svh勒索病毒介绍 svh勒索病毒是一种恶意软件&#xff0c;它通过加密受害者的文件并要求支付赎金来解锁&#xff0c;从而达到勒索的目的。这种病毒已经存在了数年&#xff0c;并且不断演变&#xff0c;形成了多种不同的家族和变种。如果您的数据承载着…

接口测试-笔记

Date 2024年4月23日21:19:51 Author KarrySmile 1. 前言 因为想更加规范地开发接口&#xff0c;同时让自己测试接口的时候更加高效&#xff0c;更好地写好接口文档。所以学习黑马的《接口自动化测试》课程。链接&#xff1a;黑马程序员软件测试接口自动化测试全套视频教程&a…

Maven基础篇6

Idea环境中资源上传与下载 具体问题本地仓库如何与私服打交道&#xff1b; 本地仓库向私服上传文件&#xff0c;上传的文件位置在哪里&#xff1f; 访问私服配置相关信息&#xff1a;用户名密码&#xff1b; 下载东西&#xff0c;需要的各种信息&#xff0c;需要的仓库组的…

TDengine高可用探讨

提到数据库&#xff0c;不可避免的要考虑高可用HA&#xff08;High Availability&#xff09;。但是很多人对高可用的理解并不是很透彻。 要搞清高可用需要回答以下几个问题&#xff1a; 什么是高可用&#xff1f;为什么需要高可用&#xff1f;高可用需要达到什么样的目标&am…

【面试经典 150 | 数组】反转字符串中的单词

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;模拟实现方法二&#xff1a;使用库函数 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本…

公园景区伴随音乐系统-公园景区数字IP广播伴随音乐系统建设指南

公园景区伴随音乐系统-公园景区数字IP广播伴随音乐系统建设指南 由北京海特伟业任洪卓发布于2024年4月23日 随着“互联网”被提升为国家战略&#xff0c;传统行业与互联网的深度融合正在如火如荼地展开。在这一大背景下&#xff0c;海特伟业紧跟时代步伐&#xff0c;凭借其深厚…

Security用户管理(一)

Security初探(三)-CSDN博客 Security的身份验证流程: AuthenticationFilter拦截请求并将身份验证职能委托给AuthticationManager.为了实现身份验证逻辑,AuthticationManager会使用身份验证程序.为了检查用户名和密码,AuthenticationProvider会使用UserDetailsService和Passwor…

爱上JDK源码阅读-枚举类

在日常开发中&#xff0c;经常会用到枚举类。这篇文章主要探讨一下枚举类和普通类有什么区别&#xff0c;以及编译过程中偷偷做了什么事情。 知识点 枚举类的本质编译器对枚举类的改动 先看一段简单的枚举类代码&#xff1a; enum StatusType {ON(1) ,OFF(2);StatusType(int …

mongodb 安装问题

1. mongodb启动时显示 Illegal instruction (core dumped) mongodb 5.0之后(包括5.0) 开始使用需要使用 AVX 指令集 2.启动时报错 ERROR: child process failed, exited with 1 通过指令 bin/mongod --repair 查看报错信息 根据报错信息进行修改 3. 配置服务器添加节点时…
最新文章