Qt 中图像的绘制

Qt中的绘图类

以下是常见的绘图类

绘图QPainterQBrush
QFont
QPen
QColor
QPaintDeviceQGLFramebufferObject
QGLPixelBuffer
QOpenGLPaintDevice
QPagedPaintDeviceQPdfWriter
QPrinter
QPaintDeviceWindowQOpenGLWindow
QRasterWindow
QRasterWindow
QRasterWindow
QImage
QPicture
QPixmapQBitmap
QPaintEngine

Qt中常见2D绘图的介绍

Qt有个绘画系统,这个系统是能够使用相同的API在屏幕和打印设备上进行绘画,主要基于主要基于QPainter、QPaintDevice和QPaintEngine类。

QPainter用于执行绘图操作,QPaintDevice是可以使用QPainter在其上绘制的二维空间的抽象,QPaintEngine提供了画家用于在不同类型的设备上绘制的接口。QPaintEngine类由QPainter和QPaintDevice内部使用,并且对应用程序程序员隐藏,除非他们创建自己的设备类型。

QPainter介绍

QPainter提供了全面的函数来完成大多数GUI绘图程序所需的功能。它可以画任何东西,从简单的线条到复杂的形状圆和和弦。它还可以绘制对齐的文本和像素图。通常,它在“自然”坐标系中绘制,但它也可以进行视图和世界变换。QPainter可以对继承QPaintDevice类的任何对象进行操作。

QPainter的常见用途是在小部件的绘画事件中:构造和自定义(例如设置笔或画笔)画家。然后画画。请记住在绘制后销毁QPainter对象。例如:

void SimpleExampleWidget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.setPen(Qt::blue);painter.setFont(QFont("Arial", 30));painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

QPainter的核心功能是绘图,但该类还提供了几个功能,允许您自定义QPainter设置及其渲染质量,以及其他启用剪裁的功能。此外,可以通过指定画家的构图模式来控制不同形状如何合并在一起。

isActive()函数指示画家是否处于活动状态。painter由begin()函数和接受QPaintDevice参数的构造函数激活。end()函数和析构函数会将其停用。

注意:当paintdevice是一个小部件时,QPainter只能在paintEvent()函数内部或在paintEvent()调用的函数中使用。

QPaintDevice介绍

QPaintDevice类是可以绘制的对象的基类,即QPainter可以在任何QPaintDivice子类上绘制。QPaintDevice的绘图功能由QWidget、QImage、QPixmap、QPicture、QPrinter和QOpenGLPaintDevice实现。

警告:Qt要求在创建任何绘制设备之前存在QGuiApplication对象。绘制设备访问窗口系统资源,并且在创建应用程序对象之前不会初始化这些资源。

QWidget

QWidget是所有界面控件元素的基类。QWidget可以捕获鼠标、键盘和其他事件并且可以在界面字自己绘制自己显示界面。

QImage

QImage类为I/O以及直接像素访问和操作而设计和优化提供了一种独立于硬件的图像表示。QImage支持多种图像格式,包括单色、8位、32位和阿尔法混合图像。

使用QImage作为绘制设备的一个优点是,可以以独立于平台的方式保证任何绘制操作的像素精度。另一个好处是绘画可以在当前GUI线程之外的另一个线程中执行。

QPixmap

QPixmap类是为在屏幕上显示图像设计和优化提供的一种屏幕外图像表示。与QImage不同,像素图中的像素数据是内部的,由底层窗口系统管理,即只能通过QPainter功能或将QPixmap转换为QImage来访问像素。

为了使用QPixmap优化绘图,Qt提供了QPixmapCache类,该类可用于存储生成成本高昂的临时像素图,而无需使用超过缓存限制的存储空间。

Qt还提供了QBitmap便利类,继承了QPixmap。QBitmap保证单色(1位深度)像素图,主要用于创建自定义QCursor和QBrush对象,构建QRegion对象。

QPicture

QPicture类是一个用于记录和回放QPainter命令绘画设备。图片以独立于平台的格式将画家命令序列化到IO设备。QPicture也与分辨率无关,即QPicture可以显示在不同的设备上(例如svg、pdf、ps、打印机和屏幕)看起来相同。

Qt提供了QPicture::load()和QPicture::save()函数,以及用于加载和保存图片的流式操作符。

Qt中坐标系的转换

在Qt中通常QPainter在设置自己额度坐标系(通常是像素)上运行。默认坐标系的坐标原点是在左上角。为了绘图方便QPainter提供了一系列的坐标转换函数。

最常用的变换是缩放、旋转、平移和剪切。使用scale()函数按给定偏移量缩放坐标系,使用rotate()函数顺时针旋转坐标系,并使用translate()平移坐标系(即向点添加给定偏移量)。也可以使用shear()函数围绕原点扭曲坐标系。

绘图设备的物理坐标系是基本的坐标系(默认坐标系),可以通过QPainter中函数进行转换为逻辑坐标。在此基础上Qt还提供了视口坐标系和窗口坐标系。视口坐标系表示的绘图设备的任意一个矩形区域的物理坐标,默认情况下视口就等于绘图设备的整个矩形区域。

视口与窗口是同一个矩形,只不过窗口用的是逻辑坐标系,坐标原点为视口的中心点。

Qt中图像的绘制

painter有绘制像素图/图像的函数,即drawPixmap()、drawImage()和drawTiledPixmap()。drawPixmap()和drawImage()都会产生相同的结果,只是drawPixmap()在屏幕上更快,而drawImages()在QPrinter或其他设备上可能更快。

为了使用QPainter获得最佳渲染效果,您应该使用独立于平台的QImage作为绘制设备;即使用QImage将确保结果在任何平台上具有相同的像素表示。

Qt中绘图例子

以上介绍了Qt中一些绘图的相关知识,如果需要了解详细内容可以查看qt的官方文档。

绘图步骤:

1、创建QPainter对象,可以在创建构造的时候传入绘图设备。可以在不使用参数在需要绘图的时候使用begin函数传入绘图设备,在绘制结束之后使用end函数结束绘图,不然或出现卡死的状态。

2、使用QPainter中的绘图函数进行绘图。

1、在QWidget中绘制

在Qt中绘制图像有两种情况,第一种就是绘制的当前窗口就是QWidget,因此只需要在重载paintEvent函数即可在此函术中使用painter画家画图。

另一种就是给当前窗口中的子窗体QWidget绘制图像,这时候也有两种方式:

1、自定义一个父类继承QWidget,并将当前窗口中QWidget窗口提升为自定义的QWidget类,在自定义的QWidget类中重载paintEvent函数实现绘图。

    //1、创建画家QPainter widgetm_painter = new QPainter();
void MainWindow::paintEvent(QPaintEvent *)
{drawForWidget();
}void MainWindow::drawForWidget()
{m_painter->begin(this);//提供画笔QPen pen;pen.setColor(QColor(Qt::red));pen.setWidth(3);m_painter->setPen(pen);//绘制一条直线m_painter->drawLine(0,0,20,20);m_painter->end();
}

2、使用事件过滤器,首先在QWidget中插入事件过滤器,之后再当前窗体所在父窗口的cpp文件中重载事件过滤器,通过事件过滤器中的判断实现绘图。在此之前还需要再父类的绘图事件函数中发出绘图事件。

    //1、创建画家QPainter widgetm_painter = new QPainter();ui->widget->installEventFilter(this);
void MainWindow::paintEvent(QPaintEvent *)
{drawForWidget();
}void MainWindow::drawForWidget()
{m_painter->begin(ui->widget);//提供画笔QPen pen;pen.setColor(QColor(Qt::red));pen.setWidth(3);m_painter->setPen(pen);//绘制一条直线m_painter->drawLine(0,0,20,20);m_painter->end();
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{if(watched == ui->widget && event->type() == QEvent::Paint)//发生绘图事件,且是在widget上发生的{QPainter painter(ui->widget);// 设置画笔样式QPen pen(Qt::red);pen.setWidth(3);painter.setPen(pen);// 绘制圆形QRectF rectangle(10.0, 20.0, 80.0, 80.0);    // 圆形所在矩形位置和大小painter.drawEllipse(rectangle);return true;}elsereturn false;
}

2、在Image绘图设备中绘图

Qt中在Image中绘制图片的时候方法和之前的步骤一样,唯一有区别的地方就是在QImage中绘制图的时候不需要在paintEvent绘图事件中执行。在函数任意调用的到的地方执行即可。

void MainWindow::drawForImage()
{QImage m_image;m_image = QImage(100,100, QImage::Format_ARGB32/*_Premultiplied*/);QPainter pt(&m_image);//提供画笔QPen pen;pen.setColor(QColor(Qt::red));pen.setWidth(3);pt.setPen(pen);//绘制一条直线pt.drawLine(10,0,10,100);//绘制直线pt.drawEllipse(QRect(10,0,100,100));//绘制椭圆pt.drawText(10,10,"绘制在Image");m_image.save("C:\\Users\\admin\\Desktop\\ship\\output.jpg");//保存到本地文件ui->label->setPixmap(QPixmap::fromImage(m_image));//显示到界面
}

在这里使用QImage绘图的是有会有一个问题:

问题:QPainter::begin: Paint device returned engine == 0, type: 3

出现原因:是由于创建QImage对象的时候没有给图像指定大小,出现的问题。

解决办法:在创建QImage绘图设备的时候指定QImage对象的大小。

3、在QPixmap中绘制图

Qt中在QImage和QPixmap绘图思路和方法一样,只不过是绘图设备不一样而已。

    //1、创建画家QPainter widgetm_painter = new QPainter();
void MainWindow::drawForQPixmap()
{QPixmap pixmap(200,200);m_painter->begin(&pixmap);//提供画笔QPen pen;pen.setColor(QColor(Qt::red));pen.setWidth(3);m_painter->setPen(pen);//绘制一条直线m_painter->drawLine(10,10,10,100);//绘制直线m_painter->drawEllipse(QRect(50,50,200,200));//绘制椭圆m_painter->drawText(20,10,"绘制在pixmap");pixmap.save("C:\\Users\\admin\\Desktop\\ship\\pixmap.jpg");//保存到本地文件ui->label->setPixmap(pixmap);//显示到界面}

其他

在qt绘图中涉及到了很多类和,其中主要涉及的有QPainter、QWidget、QImage、QPixmap、QColor、QPen、QBrush等相关类。如果想绘制更精致更好的曲线需要详细去了解相关的类。以上例子只是做了一个最基础、最简单的绘图。

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

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

相关文章

【Excel】【latex】将EXCEL中单元格的计算关系还原为公式,用c#重构

在excel中,将很多个单元格,及其内部的公式,用文本的形式复制出来 Ctrl ~将 Excel 切换到公式视图,可以看到单元格中的公式,而不是公式的结果。 像平常一样复制和粘贴单元格。粘贴时,会看到的是单元格中的…

Android studio控制台 输出乱码解决方法

在AS的安装目录,找到 studio64.exe.vmoptions 文件, 用编辑器打开文件,在最后面加上下面的代码: -Defile.encodingUTF-8然后 重启AS。 注意: 下面两种方式也能打开studio64.exe.vmoptions 文件,但是需要确…

【ELK 使用指南】ELK + Filebeat 分布式日志管理平台部署

ELK和EFLK 一、前言1.1 日志分析的作用1.2 需要收集的日志1.3 完整日志系统的基本特征 二、ELK概述2.1 ELK简介2.2 为什么要用ELK?2.3 ELK的组件 三、ELK组件详解3.1 Logstash3.1.1 简介3.1.2 Logstash命令常用选项3.1.3 Logstash 的输入和输出流3.1.4 Logstash配置文件 3.2 E…

log4cpp封装成独立的类(单例模式)

一、编译安装 二、封装使用 头文件Logger.h: #ifndef DISTRIBUTED_LOGGER_H_ #define DISTRIBUTED_LOGGER_H_#include <string> #include <log4cpp/Category.hh>class Logger{ public:bool init(const std::string& log_conf_file);static Logger* instance…

关于网络协议的若干问题(四)

1、QUIC 是一个精巧的协议&#xff0c;它有哪些特性&#xff1f; 答&#xff1a;QUIC 还有其他特性&#xff0c;一个是快速建立连接。另一个是拥塞控制&#xff0c;QUIC 协议当前默认使用了 TCP 协议的 CUBIC&#xff08;拥塞控制算法&#xff09;。 CUBIC 进行了不同的设计&…

Hadoop问题:start-all.sh显示未找到命令

在sbin文件夹下是start-all.sh可以运行的&#xff0c;但是到了别的文件夹下就不行了&#xff0c;于是想到了是文件路径问题&#xff0c;因为hadoop环境是和java环境一起配置的导致sbin写成了bin 解决办法&#xff1a; 打开.bashrc配置hadoop的环境变量 sudo vim ~/.bashrc …

nodejs+vue教学辅助管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

Folium 笔记:使用PopUp突出subzone的空间分布

0 效果图 点开某一个区域后&#xff0c;内容是这个区域的用地类型分布 1 读取数据 import folium import matplotlib.pyplot as plt import re import geopandas as gpd subzonegpd.read_file(MasterPlan2019PlanningAreaBoundaryNoSea.geojson) subzone 2 提取subzone 信息 …

从零开始的stable diffusion

stable diffusion真的是横空出世&#xff0c;开启了AIGC的元年。不知你是否有和我一样的困惑&#xff0c;这AI工具好像并不是那么听话&#xff1f; 前言 我们该如何才能用好stable diffusion这个工具呢&#xff1f;AI究竟在stable diffusion中承担了什么样的角色&#xff1f;如…

分享一个查询OpenAI Chatgpt key余额查询的工具网站

OpenAI Key 余额查询工具 欢迎使用 OpenAI Key 余额查询工具网站&#xff01;这个工具可以帮助您轻松地验证您的 OpenAI API 密钥&#xff0c;并查看您的余额。 http://tools.lbbit.top/check_key/ 什么是 OpenAI Key 余额查询工具&#xff1f; OpenAI Key 余额查询工具是一…

PCL点云处理之包含坐标、颜色信息的PFHRGB点特征直方图计算(二百一十六)

PCL点云处理之包含坐标、颜色信息的PFHRGB点特征直方图计算(二百一十六) 一、算法介绍二、代码实现一、算法介绍 在前文中计算了点特征直方图PFH,利用了点云的三维坐标信息,这里介绍考虑颜色信息的PFHRGB特征计算,对于该特征的使用可能有更好的效果,下面是具体的实现方法…

Java--基本语法

一、java转义字符 \t&#xff1a;一个制表符&#xff0c;实现对齐的功能\n&#xff1a;换行符\\&#xff1a;一个 \\"&#xff1a;一个“\&#xff1a;一个\r&#xff1a;一个回车 二、注释 单行注释&#xff1a; // 内容多行注释&#xff1a;/* 内容 */文档注释&#…

python实现图像的直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分配图像中的像素值&#xff0c;使得图像的像素值分布更加均匀&#xff0c;增强图像的对比度&#xff0c;从而改善图像的视觉效果。 直方图均衡化的过程如下&#xff1a; 灰度转换&#xff1a;如果图像是彩色…

手写单例模式

一、单例模式的定义 定义&#xff1a; 确保一个类只有一个实例&#xff0c;并提供该实例的全局访问点。 这样做的好处是&#xff1a;有些实例&#xff0c;全局只需要一个就够了&#xff0c;使用单例模式就可以避免一个全局使用的类&#xff0c;频繁的创建与销毁&#xff0c;耗…

露营装备经营商城小程序搭建

近几年露营人群逐渐增加&#xff0c;相应的装备商也多了起来&#xff0c;各种分类商品在一定程度上销量都非常不错&#xff0c;然而传统线下门店经营方面&#xff0c;面对的痛点也不少。 通过【雨科】平台搭建露营装备商城&#xff0c;让客户多场景平台随时购物&#xff0c;多流…

【Java学习之道】线程的概念与作用

引言 今天我们将探索多线程编程的基础概念和作用。对于初学者来说&#xff0c;掌握多线程编程是迈向Java高级技能的重要一步。通过本章的学习&#xff0c;你将了解线程是什么以及它在程序开发中的重要性&#xff0c;为你进一步深入学习和实际工作打下坚实的基础。让我们一起来…

基于SpringBoot的旅游网站开题报告

一、选题背景 随着旅游业的蓬勃发展和人们对旅游需求的增长&#xff0c;开发一个基于Spring Boot的旅游网站具有重要的意义。传统的旅行社模式逐渐不能满足人们个性化、多样化的旅游需求&#xff0c;因此开发一个在线旅游网站能够为用户提供更加便捷、灵活、个性化的旅游服务&…

《向量数据库指南》——Milvus Cloud和Elastic Cloud 特性对比

随着以 Milvus 为代表的向量数据库在 AI 产业界越来越受欢迎,诸如 Elasticsearch 之类的传统数据库和检索系统也开始行动起来,纷纷在快速集成专门的向量检索插件方面展开角逐。 例如,在提供类似插件的传统数据库中,Elasticsearch 8.0 首屈一指,推出了包括向量插入和最相似…

【软考】9.2 串/数组/矩阵/广义表/树

《字符串》 一种特殊的线性表&#xff0c;数据元素都为字符模式匹配&#xff1a;寻找子串第一次在主串出现的位置 模式匹配算法 1. 暴力破解法&#xff08;布鲁特-福斯算法&#xff09; 主串与子串一个个匹配效率低 2. KMP算法 主串后缀和子串前缀能否找到一样的元素&#xf…

ARM day9

src/key_it.c #include "key_it.h" #include "led.h" void key_it_config() {//RCC使能GPIOF时钟RCC->MP_AHB4ENSETR | (0x1<<5);//设置PF9 PF7 PF8GPIO输入//PF9GPIOF->MODER & (~(0x3<<18));//PF8GPIOF->MODER & (~(0x3&l…