Qt之2D绘图
Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,主要基于QPainter、QPaintDevice和QPaintEngine这3个类。其中,QPainter类用来执行绘图操作;QPaintDevice类提供绘图设备(绘图设备类QPaintDevice是所有可以绘制的对象的基类,它
Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,主要基于QPainter、QPaintDevice和QPaintEngine这3个类。其中,QPainter类用来执行绘图操作;QPaintDevice类提供绘图设备(绘图设备类QPaintDevice是所有可以绘制的对象的基类,它的子类主要有QWidget、QPixmap、QPicture、QImage和QPrinter),是一个二维空间的抽象,可以使用QPainter在其上进行绘制;QPaintEngine类提供了一些接口,可以用于QPainter在不同的设备上进行绘制。
绘图系统中由QPainter来完成具体的绘制操作,提供了大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。重点:QPainter一般在一个部件重绘(Paint Event)的处理函数paintEvent()中绘制;首先要创建QPainter对象,再进行图形的绘制,最后销毁QPainter对象。
QPainter提供的常用图形绘制函数
实例代码如下:
#include "widget.h" #include "ui_widget.h" #include <qpainter> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); //绘制线条 painter.drawLine(QPoint(0, 0), QPoint(100, 100)); //创建画笔 QPen pen(Qt::green, 5, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin); //使用画笔 painter.setPen(pen); QRectF rectangle(70.0, 40.0, 80.0, 60.0); int startAngle = 30 * 16; int spanAngle = 120 * 16; //绘制圆弧 painter.drawArc(rectangle, startAngle, spanAngle); //重新设置画笔 pen.setWidth(1); pen.setStyle(Qt::SolidLine); painter.setPen(pen); //绘制一个矩形 painter.drawRect(160, 20, 50, 40); //创建画刷 QBrush brush(QColor(0, 0, 255), Qt::Dense4Pattern); //使用画刷 painter.setBrush(brush); //绘制椭圆 painter.drawEllipse(220, 20, 50, 50); //设置纹理 brush.setTexture(QPixmap("../yafeilinux.png")); //重新使用画刷 painter.setBrush(brush); //定义四个点 static const QPointF points[4] = { QPointF(270.0, 80.0), QPointF(290.0, 10.0), QPointF(350.0, 30.0), QPointF(390.0, 70.0) }; //使用四个点绘制多边形 painter.drawPolygon(points, 4); //使用画刷填充一个矩形区域 painter.fillRect(QRect(10, 100, 150, 20), QBrush(Qt::darkYellow)); //擦除一个矩形区域的内容 painter.eraseRect(QRect(50, 0, 50, 120)); //线性渐变 QLinearGradient linearGradient(QPointF(40, 190), QPointF(70, 190)); //插入颜色 linearGradient.setColorAt(0, Qt::yellow); linearGradient.setColorAt(0.5, Qt::red); linearGradient.setColorAt(1, Qt::green); //指定渐变区域以外的区域的扩散方式 linearGradient.setSpread(QGradient::RepeatSpread); //使用渐变作为画刷 painter.setBrush(linearGradient); painter.drawRect(10, 170, 90, 40); //辐射渐变 QRadialGradient radialGradient(QPointF(200, 190), 50, QPointF(275, 200)); radialGradient.setColorAt(0, QColor(255, 255, 100, 150)); radialGradient.setColorAt(1, QColor(0, 0, 0, 50)); painter.setBrush(radialGradient); painter.drawEllipse(QPointF(200, 190), 50, 50); //锥形渐变 QConicalGradient conicalGradient(QPointF(350, 190), 60); conicalGradient.setColorAt(0.2, Qt::cyan); conicalGradient.setColorAt(0.9, Qt::black); painter.setBrush(conicalGradient); painter.drawEllipse(QPointF(350, 190), 50, 50); //画笔使用线性渐变来绘制直线和文字 painter.setPen(QPen(linearGradient,2)); painter.drawLine(0, 280, 100, 280); painter.drawText(150, 280, tr("helloQt!")); }</qpainter>
渐变填充:在Qt中,QGradient类就是用来和QBrush一起制定渐变填充的。
1、线性渐变在开始点和结束点之间插入颜色;
2、辐射渐变在焦点和环绕它的圆环间插入颜色;
3、锥形渐变在圆心周围插入颜色;
这3钟渐变分别由QGradient的3个子类来表示:QLinearQradient表示线性渐变、QRadialGradient表示辐射渐变和QConicalGradient表示锥形渐变。
抗锯齿渲染
QPainter进行绘制时可以使用QPainter::setRenderHint()函数渲染提示来指定是否要使用坑锯齿功能,其功能主要是对图像的边缘进行平滑处理,使其看起来更加柔和流畅。
坐标变换
QPainter的逻辑坐标与绘图设备(绘图设备的默认坐标系统中原点是(0, 0))的物理坐标之间的映射由QPainter的变换矩阵、视口和窗口处理,逻辑坐标和物理坐标默认是一致的。绘图时可以使用QPainter::scale()函数缩放坐标系统;使用QPainter::rotate()函数顺时针旋转坐标系统;使用QPainter::translate()函数平移坐标系统;使用QPainter::shear()围绕原点来扭曲坐标系统。
1、基本变换
坐标系统的2D变换由QTransform类实现,而且QTransform类对象可以存储多个变换操作,当同样的变换要多次使用时,建议使用QTransform类对象。坐标系统的变换是通过变换矩阵实现的,可以在平面上变换一个点到另一个点。进行所有变换操作的变换矩阵都可以使用QPainter::worldTransform()函数获得,如果要设置一个变换矩阵,可以使用QPainter::setWorldTransform()函数,这两个函数也可以分别使QPainter::transform()和QPainter::setTransform()函数来替代。
在进行变换操作时,可能需要多次改变坐标系统再恢复,这样就显得很乱,而且很容易出现操作错误。这时可以使用QPainter::save()函数来保存QPainter的变换矩阵,它会把变换矩阵保存到一个内部栈中,然后在需要恢复变换矩阵时再使用QPainter::restore()函数将其弹出。
2、窗口——视口转换
使用QPainter绘制时会使用到逻辑坐标,然后再转换为绘图设备的物理坐标。逻辑坐标到物理坐标的映射由QPainter的worldTransform()函数、QPainter的viewport()以及window()函数进行处理。其中,视口表示物理坐标下制定的一个任意矩形,而窗口表示逻辑坐标下的相同矩形。默认的,逻辑坐标和屋里坐标是重合的,都相当于绘图设备上的矩形。一个很好的办法是让视口和窗口维持相同的宽高比来防止变形:
int side = qMin(width(), height()); int x = (width() / 2); int y = (height() / 2); //设置窗口—视口转换 painter.setViewport(x, y, side, side);
窗口——视口转换仅仅是线性变换,不会执行裁剪操作,这就意味着如果绘制范围超出了当前设置的窗口,那么仍然会使用相同的线性代数方法将绘制变换到视口上。
#include "widget.h" #include "ui_widget.h" #include <qpainter> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); //填充界面背景为白色 painter.fillRect(rect(), Qt::white); painter.setPen(QPen(Qt::red, 11)); //绘制一条线段 painter.drawLine(QPoint(5, 6), QPoint(100, 99)); //将坐标系统进行平移,使(200, 150)点作为原点 painter.translate(200, 150); //开启抗锯齿 painter.setRenderHint(QPainter::Antialiasing); //重新绘制相同的线段 painter.drawLine(QPoint(5, 6), QPoint(100, 99)); //保存painter的状态 painter.save(); //将坐标系统旋转90度 painter.rotate(90); painter.setPen(Qt::cyan); //重新绘制相同的线段 painter.drawLine(QPoint(5, 6), QPoint(100, 99)); //恢复painter的状态 painter.restore(); painter.setBrush(Qt::darkGreen); //绘制一个矩形 painter.drawRect(-50, -50, 100, 50); painter.save(); //将坐标系统进行缩放 painter.scale(0.5, 0.4); painter.setBrush(Qt::yellow); //重新绘制相同的矩形 painter.drawRect(-50, -50, 100, 50); painter.restore(); painter.setPen(Qt::blue); painter.setBrush(Qt::darkYellow); //绘制一个椭圆 painter.drawEllipse(QRect(60, -100, 50, 50)); //将坐标系统进行扭曲 painter.shear(1.5, -0.7); painter.setBrush(Qt::darkGray); //重新绘制相同的椭圆 painter.drawEllipse(QRect(60, -100, 50, 50)); }</qpainter>
#include "widget.h" #include "ui_widget.h" #include <qpainter> #include <qtooltip> #include <qmouseevent> #include <qtimer> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); setMouseTracking(true); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1000); angle = 0; } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { angle += 10; if(angle == 360) angle = 0; int side = qMin(width(), height()); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QTransform transform; transform.translate(width()/2, height()/2); transform.scale(side/300.0, side/300.0); transform.rotate(angle); painter.setWorldTransform(transform); painter.drawEllipse(-120, -120, 240, 240); painter.drawLine(0, 0, 100, 0); } void Widget::mouseMoveEvent(QMouseEvent *event) { QString pos = QString("%1,%2").arg(event->pos().x()).arg(event->pos().y()); QToolTip::showText(event->globalPos(), pos, this); }</qtimer></qmouseevent></qtooltip></qpainter>

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

通用矩阵乘法(GeneralMatrixMultiplication,GEMM)是许多应用程序和算法中至关重要的一部分,也是评估计算机硬件性能的重要指标之一。通过深入研究和优化GEMM的实现,可以帮助我们更好地理解高性能计算以及软硬件系统之间的关系。在计算机科学中,对GEMM进行有效的优化可以提高计算速度并节省资源,这对于提高计算机系统的整体性能至关重要。深入了解GEMM的工作原理和优化方法,有助于我们更好地利用现代计算硬件的潜力,并为各种复杂计算任务提供更高效的解决方案。通过对GEMM性能的优

7月29日,在AITO问界第四十万台新车下线仪式上,华为常务董事、终端BG董事长、智能汽车解决方案BU董事长余承东出席发表演讲并宣布,问界系列车型将于今年8月迎来华为干昆ADS3.0版本的上市,并计划在8月至9月间陆续推送升级。 8月6日即将发布的享界S9将首发华为ADS3.0智能驾驶系统。华为干昆ADS3.0版本在激光雷达的辅助下,将大幅提升智驾能力,具备融合端到端的能力,并采用GOD(通用障碍物识别)/PDP(预测决策规控)全新端到端架构,提供车位到车位智驾领航NCA功能,并升级CAS3.0全

屏幕截图功能在您的iPhone上不起作用吗?截屏非常简单,因为您只需同时按住“提高音量”按钮和“电源”按钮即可抓取手机屏幕。但是,还有其他方法可以在设备上捕获帧。修复1–使用辅助触摸使用辅助触摸功能截取屏幕截图。步骤1–转到您的手机设置。步骤2–接下来,点击以打开“辅助功能”设置。步骤3–打开“触摸”设置。步骤4–接下来,打开“辅助触摸”设置。步骤5–打开手机上的“辅助触摸”。步骤6–打开“自定义顶级菜单”以访问它。步骤7–现在,您只需将这些功能中的任何一个链接到屏幕捕获即可。因此,点击那里的首

MetaMask(中文也叫小狐狸钱包)是一款免费的、广受好评的加密钱包软件。目前,BTCC已支持绑定MetaMask钱包,绑定后可使用MetaMask钱包进行快速登入,储值、买币等,且首次绑定还可获得20USDT体验金。在BTCCMetaMask钱包教学中,我们将详细介绍如何注册和使用MetaMask,以及如何在BTCC绑定并使用小狐狸钱包。MetaMask钱包是什么?MetaMask小狐狸钱包拥有超过3,000万用户,是当今最受欢迎的加密货币钱包之一。它可免费使用,可作为扩充功能安装在网络

网易邮箱,作为中国网民广泛使用的一种电子邮箱,一直以来以其稳定、高效的服务赢得了用户的信赖。而网易邮箱大师,则是专为手机用户打造的邮箱软件,它极大地简化了邮件的收发流程,让我们的邮件处理变得更加便捷。那么网易邮箱大师该如何使用,具体又有哪些功能呢,下文中本站小编将为大家带来详细的内容介绍,希望能帮助到大家!首先,您可以在手机应用商店搜索并下载网易邮箱大师应用。在应用宝或百度手机助手中搜索“网易邮箱大师”,然后按照提示进行安装即可。下载安装完成后,我们打开网易邮箱账号并进行登录,登录界面如下图所示

在如今云存储已经成为我们日常生活和工作中不可或缺的一部分。百度网盘作为国内领先的云存储服务之一,凭借其强大的存储功能、高效的传输速度以及便捷的操作体验,赢得了广大用户的青睐。而且无论你是想要备份重要文件、分享资料,还是在线观看视频、听取音乐,百度网盘都能满足你的需求。但是很多用户们可能对百度网盘app的具体使用方法还不了解,那么这篇教程就将为大家详细介绍百度网盘app如何使用,还有疑惑的用户们就快来跟着本文详细了解一下吧!百度云网盘怎么用:一、安装首先,下载并安装百度云软件时,请选择自定义安装选

虽然距离iPhone16系列发布还要许久,但外观和配置相关爆料就没断过。据韩国媒体SisaJournal报道,苹果计划在即将推出的iPhone16系列手机中引入全新的超窄边框技术。该技术涉及将内部铜线卷成更紧凑的结构,以缩小手机底部显示屏的边框宽度,从而实现更大尺寸的显示屏。这一创新举措旨在提升用户体验,让用户享受更广阔的视野和更沉浸式的娱乐体验。苹果一直致力于不断改进其产品设计和技术,为用户带来更先进的功能和性能。iPhone16系列手机的推出将进一步巩固苹果在智能另据@刹那数码爆料,苹果新一

7月23日消息,博主数码闲聊站爆料称,小米15Pro电池容量增大至6000mAh,支持90W有线闪充,这将是小米数字系列电池最大的Pro机型。此前数码闲聊站透露,小米15Pro的电池拥有超高能量密度,硅含量远高于竞品。硅基电池在2023年大规模试水后,第二代硅负极电池被确定为行业未来发展方向,今年将迎来直接竞争的高峰。1.硅的理论克容量可达4200mAh/g,是石墨克容量的10倍以上(石墨的理论克容量372mAh/g)。对于负极而言,当锂离子嵌入量达到最大时的容量为理论克容量,这意味着相同重量下
