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>采用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>

InnoDB使用redologs和undologs确保数据一致性和可靠性。1.redologs记录数据页修改,确保崩溃恢复和事务持久性。2.undologs记录数据原始值,支持事务回滚和MVCC。

EXPLAIN命令的关键指标包括type、key、rows和Extra。1)type反映查询的访问类型,值越高效率越高,如const优于ALL。2)key显示使用的索引,NULL表示无索引。3)rows预估扫描行数,影响查询性能。4)Extra提供额外信息,如Usingfilesort提示需要优化。

Usingtemporary在MySQL查询中表示需要创建临时表,常见于使用DISTINCT、GROUPBY或非索引列的ORDERBY。可以通过优化索引和重写查询避免其出现,提升查询性能。具体来说,Usingtemporary出现在EXPLAIN输出中时,意味着MySQL需要创建临时表来处理查询。这通常发生在以下情况:1)使用DISTINCT或GROUPBY时进行去重或分组;2)ORDERBY包含非索引列时进行排序;3)使用复杂的子查询或联接操作。优化方法包括:1)为ORDERBY和GROUPB

MySQL/InnoDB支持四种事务隔离级别:ReadUncommitted、ReadCommitted、RepeatableRead和Serializable。1.ReadUncommitted允许读取未提交数据,可能导致脏读。2.ReadCommitted避免脏读,但可能发生不可重复读。3.RepeatableRead是默认级别,避免脏读和不可重复读,但可能发生幻读。4.Serializable避免所有并发问题,但降低并发性。选择合适的隔离级别需平衡数据一致性和性能需求。

MySQL适合Web应用和内容管理系统,因其开源、高性能和易用性而受欢迎。1)与PostgreSQL相比,MySQL在简单查询和高并发读操作上表现更好。2)相较Oracle,MySQL因开源和低成本更受中小企业青睐。3)对比MicrosoftSQLServer,MySQL更适合跨平台应用。4)与MongoDB不同,MySQL更适用于结构化数据和事务处理。

MySQL索引基数对查询性能有显着影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

MySQL学习路径包括基础知识、核心概念、使用示例和优化技巧。1)了解表、行、列、SQL查询等基础概念。2)学习MySQL的定义、工作原理和优势。3)掌握基本CRUD操作和高级用法,如索引和存储过程。4)熟悉常见错误调试和性能优化建议,如合理使用索引和优化查询。通过这些步骤,你将全面掌握MySQL的使用和优化。

MySQL在现实世界的应用包括基础数据库设计和复杂查询优化。1)基本用法:用于存储和管理用户数据,如插入、查询、更新和删除用户信息。2)高级用法:处理复杂业务逻辑,如电子商务平台的订单和库存管理。3)性能优化:通过合理使用索引、分区表和查询缓存来提升性能。


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver CS6
视觉化网页开发工具

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中