目录
坐标变换
平移坐标轴
缩放坐标轴
旋转坐标轴
定时器加坐标轴旋转实现动画旋转
transform旋转(可设置旋转轴)
绕X轴旋转
绕Y轴旋转
绕Z轴旋转
错切
Y轴错切
X轴错切
画家的保存与坐标复原
基本图形绘制
绘制点
绘制线
绘制矩形
普通矩形绘制
圆角矩形绘制
填充矩形绘制
绘制圆形
绘制弧、扇形、弦
绘制弧
绘制扇形
绘制弦
绘制折线
绘制多边形
绘制路径
基本路径绘制
填充规则
绘制贝塞尔曲线
二次贝塞尔曲线绘制
三次贝塞尔曲线绘制
绘制文字
静态文本绘制
普通文本绘制
字体相关函数
图片绘制
QPixmap
指定位置裁剪
透明绘制
瓦片图绘制
图像的保存
QImage
QPicture
QBitmap
碰撞检测
坐标变换
平移坐标轴
painter.translate(50,50);
painter.drawPixmap(0,0, QPixmap(":/bk1.jpg").scaled(150,100));
缩放坐标轴
painter.drawPixmap(0,0, QPixmap(":/bk1.jpg").scaled(100,100));
painter.scale(0.5,0.5);
painter.drawPixmap(200,200, QPixmap(":/bk1.jpg").scaled(100,100));
旋转坐标轴
painter.translate(width()/2 - 100,height()/2 - 100);
painter.rotate(30); // 角度(默认以坐标原点旋转)(正数顺时针,负数逆时针)
painter.drawPixmap(0,0, QPixmap(":/bk1.jpg").scaled(200,200));
定时器加坐标轴旋转实现动画旋转
QTimer* timer = new QTimer(this);
timer->callOnTimeout(this, QOverload<>::of(&QWidget::update));
timer->start(10);
static int angle = 0;
painter.translate(width()/2 - 100,height()/2 - 100);
painter.rotate(angle++);
painter.drawPixmap(0,0, QPixmap(":/bk1.jpg").scaled(200,200));
transform旋转(可设置旋转轴)
绕X轴旋转
QTimer* timer = new QTimer(this);
timer->callOnTimeout(this, QOverload<>::of(&QWidget::update));
timer->start(10);
//
static int angle = 0;
QTransform transform;
transform.rotate(angle++, Qt::XAxis); // 绕X轴旋转
painter.setTransform(transform);
painter.drawPixmap(0, 0 , QPixmap(":/bk1.jpg").scaled(200,200));
绕Y轴旋转
QTimer* timer = new QTimer(this);
timer->callOnTimeout(this, QOverload<>::of(&QWidget::update));
timer->start(10);
//
static int angle = 0;
QTransform transform;
transform.rotate(angle++, Qt::YAxis); // 绕Y轴旋转
painter.setTransform(transform);
painter.drawPixmap(0, 0 , QPixmap(":/bk1.jpg").scaled(200,200));
绕Z轴旋转
QTimer* timer = new QTimer(this);
timer->callOnTimeout(this, QOverload<>::of(&QWidget::update));
timer->start(10);
//
static int angle = 0;
QTransform transform;
transform.rotate(angle++, Qt::ZAxis); // 绕Z轴旋转
painter.setTransform(transform);
painter.drawPixmap(0, 0 , QPixmap(":/bk1.jpg").scaled(200,200));
错切
Y轴错切
// y轴错切
painter.translate(width()/2 - 100, height()/2 -100);
painter.shear(0, 0.5); // [-1, 1]
painter.drawPixmap(0, 0 , QPixmap(":/bk1.jpg").scaled(200,200));
X轴错切
// x轴错切
painter.translate(width()/2 - 100, height()/2 -100);
painter.shear(0.5, 0); // [-1, 1]
painter.drawPixmap(0, 0 , QPixmap(":/bk1.jpg").scaled(200,200));
画家的保存与坐标复原
painter.save(); // 画家状态保存
// 坐标变换
// 图形绘制
painter.restore(); // 画家状态复原
基本图形绘制
绘制点
painter.setPen(Qt::red);
painter.drawPoint(50,50); // 绘制单个点
// 绘制多个点
QPoint points[] = {{0,0},{1,1},{2,2},{3,3}};
painter->drawPoints(points, 4);
// 绘制多个点
QPolygon polygon;
for(int i = 0; i < 100; i++)
{
polygon.append({i,i});
}
painter.drawPoints(polygon);
绘制线
// 绘制一条线
painter.drawLine(0,0,100,100);
// 绘制多条线
QList<QLine> lines = {{0,0,100,100}, {100,100, 0,200}};
painter.drawLines(lines);
绘制矩形
普通矩形绘制
painter.drawRect(50,50,100,100);
圆角矩形绘制
// 最后一个参数为默认值,此时第三第四个参数为具体的值
painter.drawRoundedRect(QRect(200,200,100,100), 50, 50,Qt::SizeMode::AbsoluteSize);
// 此时第三第四个参数为百分比 [0,100]
painter.drawRoundedRect(QRect(200,200,100,100), 50, 50,Qt::SizeMode::RelativeSize);
填充矩形绘制
painter.fillRect(50,50,100,100,QColor(255,0,255));
绘制圆形
painter.drawEllipse(0,0,200,200); // 矩形区域绘制
painter.drawEllipse(QPoint(100,100),50,50); // 中心点,两轴
绘制弧、扇形、弦
绘制弧
painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawArc(QRect(100,100,200,200), 0, 16 * 90);
绘制扇形
painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawPie(QRect(100,100,200,200), 0, 16 * 90);
绘制弦
painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawChord(QRect(100,100,200,200), 0, 16 * 90);
绘制折线
QPolygon poly;
poly << QPoint(0, 0) << QPoint(100,100) << QPoint(200, 100);
painter.drawPolyline(poly);
QPoint pos[3] = { QPoint(0, 0) , QPoint(100,100) , QPoint(200, 100)};
painter.drawPolyline(pos, 3);
绘制多边形
painter.setBrush(Qt::green);
QPolygon poly = {{0,0},{100,0},{100,100},{0,100},{200,0}};
painter.drawPolygon(poly);
绘制路径
基本路径绘制
painter.setBrush(Qt::green);
QPainterPath path;
path.lineTo(200,200);
path.lineTo(0,200);
path.moveTo(400,400);
path.lineTo(width(),height());
painter.drawPath(path);
填充规则
painter.setBrush(Qt::green);
QPainterPath path;
path.addRect(QRect(0,0,200,200));
path.addRect(QRect(100,100,200,200));
path.setFillRule(Qt::FillRule::WindingFill); // 缠绕填充
//path.setFillRule(Qt::FillRule::OddEvenFill); // 奇偶填充
painter.drawPath(path);
绘制贝塞尔曲线
二次贝塞尔曲线绘制
// 二次贝塞尔曲线
QPainterPath path;
path.moveTo(200,200);
path.quadTo(QPoint(300,300), QPoint(400,200));
painter.drawPath(path);
三次贝塞尔曲线绘制
// 三次贝塞尔曲线
QPainterPath path;
path.moveTo(0,0);
path.cubicTo(QPoint(10,100), QPoint(300,500), QPoint(200,200));
painter.drawPath(path);
绘制文字
静态文本绘制
// 绘制坐标即为左上角坐标
painter.drawStaticText(QPoint(0,0), QStaticText("Hello World"));
普通文本绘制
注意: 绘制文字是以左下角为原点绘制的
painter.setPen(Qt::red);
painter.setFont(QFont("微软雅黑",28,QFont::Bold,true));
painter.drawText(0,50, QString("Hello World"));
// 将绘制字体固定在矩形区域内 (会自动换行)
painter.drawText(QRect(0,0,100,200), "Hello World Hello World!");
字体相关函数
// 设置字体
painter->setFont();
// 获取字体
painter->font();
// 获取字体信息
painter->fontInfo();
// 获取字体数据
painter->fontMetrics();
图片绘制
QPixmap
针对输出显示优化的图像绘制
指定位置裁剪
painter.drawPixmap(100, 100, QPixmap("mm.jpg").scaled(100,100));
painter.drawPixmap(QRect(0,0,100,100), // 绘制位置
QPixmap("mm.jpg").scaled(100,100), // 图像
QRect(50,50,50,50)); // 裁剪区域
drawPixmap(const QPoint &point, const QPixmap &pixmap, const QRect &source)
透明绘制
分别准备一张原码图和一张掩码图
//掩码图和原图大小必须一致
//掩码图白色区域为透明,黑色区域为绘制
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
QBitmap mask("mask.jpg");
QPixmap pix = QPixmap("snowball.jpg").scaled(mask.size());
pix.setMask(mask);
painter.drawPixmap(0, 0,pix);
瓦片图绘制
// 函数原型
drawPixmapFragments(const QPainter::PixmapFragment *fragments,
int fragmentCount,
const QPixmap &pixmap,
QPainter::PixmapFragmentHints hints = PixmapFragmentHints())
QPainter::PixmapFragment pixFrag = QPainter::PixmapFragment::create(QPointF(0,0), QRectF(0,0,100,100));
painter.drawPixmapFragments(&pixFrag, 2, QPixmap("mm.jpg").scaled(100,100));
图像的保存
m_pixmap = QPixmap(640,480);
QPainter painter(&m_pixmap);
painter.fillRect(m_pixmap.rect(),Qt::blue);
// 保存图片
m_pixmap.save("hello.png");
QImage
专门进行图像处理的
QImage m_img = QImage(640,480,QImage::Format_RGBA8888);
m_img.fill(Qt::transparent);
QPainter painter(&m_img);
painter.fillRect(QRect(0,0,100,100), Qt::blue);
m_img.save("img.png");
QPicture
Qt独有的图像格式
QPainter painter;
painter.begin(&pic);
painter.drawEillipse(0,0,200,200);
painter.end();
pic.save("pic.pic");
// 绘制不能直接使用QPicture的构造函数加载文件
QPicture pict;
pict.load("pic.pic");
painter->drawPicture(0,0,pict);
QBitmap
位图(黑白图)
QBitmap bitmap("mm.jpg");
painter.drawImage(QRect(0, 0, 100, 100), bitmap.toImage());
碰撞检测
// 碰撞检测
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QStaticText>
#include <QPainterPath>
#include <QKeyEvent>
// 碰撞检测
class Sprite
{
public:
Sprite() = default;
Sprite(int x,int y,int w,int h, const QPixmap& pix)
:m_pos(x,y),m_size(w,h),m_pixmap(pix)
{
}
void draw(QPainter* painter)
{
painter->drawPixmap(QRect(m_pos,m_size), m_pixmap);
}
void setPos(int x,int y)
{
m_pos.rx() = x;
m_pos.ry() = y;
}
void moveBy(int dx,int dy)
{
m_pos.rx() += dx;
m_pos.ry() += dy;
}
void updateCollider()
{
collider.clear();
collider.addRect(QRect(m_pos, m_size));
}
void printPos()
{
qInfo() << m_pos;
}
private:
QPoint m_pos;
QSize m_size;
QPixmap m_pixmap;
public:
QPainterPath collider; // 碰撞器
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget* parent = nullptr)
:QWidget(parent)
{
resize(640,480);
sp1 = new Sprite(0,0,50,50,QPixmap("mm.jpg"));
sp2 = new Sprite(100,0,50,50, QPixmap("snowball.jpg"));
}
~Widget()
{
}
protected:
void paintEvent(QPaintEvent* ev) override
{
QPainter painter(this);
sp1->draw(&painter);
sp2->draw(&painter);
}
void keyPressEvent(QKeyEvent *ev) override
{
switch(ev->key())
{
case Qt::Key_Up:
sp2->moveBy(0, -3);
break;
case Qt::Key_Down:
sp2->moveBy(0, 3);
break;
case Qt::Key_Left:
sp2->moveBy(-3, 0);
break;
case Qt::Key_Right:
sp2->moveBy(3, 0);
break;
}
if(sp1->collider.intersects(sp2->collider))
{
sp2->setPos(width() - 50, 0);
}
update();
// 判断碰撞
sp2->updateCollider();
sp1->updateCollider();
}
private:
Sprite* sp1 = nullptr;
Sprite* sp2 = nullptr;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"