首页 数据库 mysql教程 Qt之2D绘图

Qt之2D绘图

Jun 07, 2016 pm 03:32 PM
api 使用 可以 屏幕 提供 系统 绘图

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提供的常用图形绘制函数

Qt之2D绘图

实例代码如下:

#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>
登录后复制
采用QPainter::QPainter(QPaintDevice* device)构造函数创建的对象会立即开始在设备上绘制,自动调用begin()函数,然后在QPainter的析构函数中调用end()函数结束绘制。


渐变填充:在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>
登录后复制




本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1676
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
CUDA之通用矩阵乘法:从入门到熟练! CUDA之通用矩阵乘法:从入门到熟练! Mar 25, 2024 pm 12:30 PM

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

华为干昆 ADS3.0 智驾系统 8 月上市 享界 S9 首发搭载 华为干昆 ADS3.0 智驾系统 8 月上市 享界 S9 首发搭载 Jul 30, 2024 pm 02:17 PM

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

iPhone屏幕截图不起作用:如何修复 iPhone屏幕截图不起作用:如何修复 May 03, 2024 pm 09:16 PM

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

BTCC教学:如何在BTCC交易所绑定使用MetaMask钱包? BTCC教学:如何在BTCC交易所绑定使用MetaMask钱包? Apr 26, 2024 am 09:40 AM

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

网易邮箱大师怎么用 网易邮箱大师怎么用 Mar 27, 2024 pm 05:32 PM

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

百度网盘app怎么用 百度网盘app怎么用 Mar 27, 2024 pm 06:46 PM

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

苹果 曝 iPhone16 或实现更大显示屏 苹果 曝 iPhone16 或实现更大显示屏 Mar 22, 2024 pm 06:41 PM

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

6000 毫安硅负极电池!小米 15Pro 升级再曝料 6000 毫安硅负极电池!小米 15Pro 升级再曝料 Jul 24, 2024 pm 12:45 PM

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

See all articles