问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何使用QT的QPainter绘图和实时刷新

发布网友 发布时间:2022-04-12 12:42

我来回答

3个回答

懂视网 时间:2022-04-12 17:03

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 

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(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.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);
}

热心网友 时间:2022-04-12 14:11

2D制图:CDR,3D制图:3DMax CDR:平面制图中的功能非常强大,CDR可以很完美的制作出矢量图(放大后图像不会失真)。同时CDR还集成了矢量动画、页面设计、网站制作、位图编辑和网页动画等多种功能。

热心网友 时间:2022-04-12 15:29

如何使用QT的QPa式(MFC是直接绘图,也可类似MVC),数据和视图分开,paintEvent里只
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
草青青,青青草,草上接谢珍珠宝,怕日晒怕风摇,摇看珍珠得起早 谜底是... 一加9R要不要升级ColorOS 13正式版 一加9pro怎么coloros12一加9pro升级coloros12的方法 coloros12支持哪些一加机型?coloros12支持一加机型介绍 一加9pro如何coloros12?一加9pro升级coloros12的方法 一加9pro升级coloros12拍照改善吗 我是一个高中生,职教的,我们班上有5个女生,我喜欢有一个,但追她又有... 自动挡d挡旁边的 -是什么意思? 自动挡位上的加减是什么意思? 宣传这个职位是干什么的 高中编导传媒学些什么? 翻译几句话,高手进 『出前一丁』 方便面为何那么贵 不收加一什么意思 出前一丁人物的介绍 "榨菜肉丝炒出前一丁"这个菜怎么翻译呢?出前一丁的意思好像指的是外卖 懂粤语的朋友帮个忙啦! 咁我地咪变左出前一丁麻油味law,这句话什么意思?有粤语的语法错误吗? 我在香港吃早餐的时候看到有个叫什么“出丁加一”还是“加一出丁”的。 什么意思? 捞丁是什么饭? 汤丁和捞丁是什么意思 捞丁是什么? 出前一丁保质期是多久的 一类卡网银转账一天限额多少? “出前一丁”这个名字到底什么意思? 中国银行一类卡网上支付单笔限额多少? 出前一丁是哪个国家的? 王一丁为什么叫出前一丁? 出前一丁是什么意思???好奇怪 山东淄博市博山区的有线电视开户费是怎么收的? 为什么叫出前一丁 vivo账号怎么登陆 vivo端口的诛仙手游怎么在电脑上玩,目前模拟器已下载,怎么能登陆vivo具体账号?求具体操作! 用vivo帐号怎么登录 为什么手机能登陆VIVO账户而电脑登陆不上呢? 如何低成本推广青少年篮球培训班服务? 求篮球训练营招生促销方案 篮球培训收入最大化的五个措施篮球培训收入最大化的五个措施 开发国内青少年篮球市场的办法? 想开一个暑期篮球培训班 怎样做宣传 如何办好一个篮球培训班 想和当地的一些培训机构合作开设篮球班,需要怎么做? 高人帮我做一个羽毛球和篮球培训班的推广方案主要是社区服务型为主的 我们想开个篮球培训班,现在前提是怎么招生。宣传单怎么写?具体步骤怎么样?对象是初中高中学生。求指点 求8至10岁儿童的篮球培训具体方案 监控摄像头烧毁 监控摄像头电源24v用220v直接接球机烧了 如何修呢? 监控摄像头将12V电源误接220V被烧能修好吗 《凹凸大赛》旧设格瑞为什么杀了金? 监控老是烧电源是怎么回事啊?急啊!!! 梦到自己怀孕生子