(15)Qt绘图(two)

目录

坐标变换

平移坐标轴

缩放坐标轴

旋转坐标轴

定时器加坐标轴旋转实现动画旋转

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"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石小浪♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值