• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Qt之2D绘图

mysql 搞代码 4年前 (2022-01-09) 35次浏览 已收录 0个评论

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%20"widget.h"#include%20"ui_widget.h"#include%20Widget::Widget(QWidget%20*parent)%20:%20%20%20%20QWidget(parent),%20%20%20%20ui(new%20Ui::Widget){%20%20%20%20ui->setupUi(this);}Widget::~Widget(){%20%20%20%20delete%20ui;}void%20Widget::paintEvent(QPaintEvent%20*event){%20%20%20%20QPainter%20painter(this);%20%20%20%20//绘制线条%20%20%20%20painter.drawLine(QPoint(0,%200),%20QPoint(100,%20100));%20%20%20%20//创建画笔%20%20%20%20QPen%20pen(Qt::green,%205,%20Qt::DotLine,%20Qt::RoundCap,%20Qt::RoundJoin);%20%20%20%20//使用画笔%20%20%20%20painter.setPen(pen);%20%20%20%20QRectF%20rectangle(70.0,%2040.0,%2080.0,%2060.0);%20%20%20%20int%20startAngle%20=%2030%20*%2016;%20%20%20%20int%20spanAngle%20=%20120%20*%2016;%20%20%20%20//绘制圆弧%20%20%20%20painter.drawArc(rectangle,%20startAngle,%20spanAngle);%20%20%20%20//重新设置画笔%20%20%20%20pen.setWidth(1);%20%20%20%20pen.setStyle(Qt::SolidLine);%20%20%20%20painter.setPen(pen);%20%20%20%20//绘制一个矩形%20%20%20%20painter.drawRect(160,%2020,%2050,%2040);%20%20%20%20//创建画刷%20%20%20%20QBrush%20brush(QColor(0,%200,%20255),%20Qt::Dense4Pattern);%20%20%20%20//使用画刷%20%20%20%20painter.setBrush(brush);%20%20%20%20//绘制椭圆%20%20%20%20painter.drawEllipse(220,%2020,%2050,%2050);%20%20%20%20//设置纹理%20%20%20%20brush.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(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 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));}
#include "widget.<strong>本文来源gaodai#ma#com搞@代~码^网+</strong>h"#include "ui_widget.h"#include #include #include #include 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);}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Qt之2D绘图

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址