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

(15)Qt绘图(two)_第1张图片

缩放坐标轴

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));

(15)Qt绘图(two)_第2张图片

旋转坐标轴

painter.translate(width()/2 - 100,height()/2 - 100);
painter.rotate(30); // 角度(默认以坐标原点旋转)(正数顺时针,负数逆时针)
painter.drawPixmap(0,0, QPixmap(":/bk1.jpg").scaled(200,200));

(15)Qt绘图(two)_第3张图片

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

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));

(15)Qt绘图(two)_第4张图片

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));

(15)Qt绘图(two)_第5张图片

绕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));

(15)Qt绘图(two)_第6张图片

绕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));

(15)Qt绘图(two)_第7张图片

错切

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));

 (15)Qt绘图(two)_第8张图片

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));

(15)Qt绘图(two)_第9张图片

画家的保存与坐标复原

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 lines = {{0,0,100,100}, {100,100, 0,200}};
painter.drawLines(lines);

(15)Qt绘图(two)_第10张图片

绘制矩形

普通矩形绘制

painter.drawRect(50,50,100,100);

圆角矩形绘制

// 最后一个参数为默认值,此时第三第四个参数为具体的值
painter.drawRoundedRect(QRect(200,200,100,100), 50, 50,Qt::SizeMode::AbsoluteSize);

(15)Qt绘图(two)_第11张图片

// 此时第三第四个参数为百分比 [0,100]
painter.drawRoundedRect(QRect(200,200,100,100), 50, 50,Qt::SizeMode::RelativeSize);

(15)Qt绘图(two)_第12张图片

 填充矩形绘制

painter.fillRect(50,50,100,100,QColor(255,0,255));

(15)Qt绘图(two)_第13张图片

绘制圆形

painter.drawEllipse(0,0,200,200);						// 矩形区域绘制
painter.drawEllipse(QPoint(100,100),50,50);				// 中心点,两轴

(15)Qt绘图(two)_第14张图片

绘制弧、扇形、弦

绘制弧

painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawArc(QRect(100,100,200,200), 0, 16 * 90);

(15)Qt绘图(two)_第15张图片

绘制扇形

painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawPie(QRect(100,100,200,200), 0, 16 * 90);

(15)Qt绘图(two)_第16张图片

绘制弦

painter.drawRect(100,100,200,200);
painter.setPen(Qt::red);
painter.drawChord(QRect(100,100,200,200), 0, 16 * 90);

(15)Qt绘图(two)_第17张图片

绘制折线

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);

 (15)Qt绘图(two)_第18张图片

绘制多边形

painter.setBrush(Qt::green);
QPolygon poly = {{0,0},{100,0},{100,100},{0,100},{200,0}};
painter.drawPolygon(poly);

(15)Qt绘图(two)_第19张图片

绘制路径

基本路径绘制

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);

(15)Qt绘图(two)_第20张图片

 填充规则

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);

(15)Qt绘图(two)_第21张图片

绘制贝塞尔曲线

二次贝塞尔曲线绘制

// 二次贝塞尔曲线
QPainterPath path;
path.moveTo(200,200);
path.quadTo(QPoint(300,300), QPoint(400,200));
painter.drawPath(path);

(15)Qt绘图(two)_第22张图片

三次贝塞尔曲线绘制

// 三次贝塞尔曲线
QPainterPath path;
path.moveTo(0,0);
path.cubicTo(QPoint(10,100), QPoint(300,500), QPoint(200,200));
painter.drawPath(path);

(15)Qt绘图(two)_第23张图片

绘制文字

静态文本绘制

// 绘制坐标即为左上角坐标
painter.drawStaticText(QPoint(0,0), QStaticText("Hello World"));

(15)Qt绘图(two)_第24张图片

普通文本绘制

注意: 绘制文字是以左下角为原点绘制的

painter.setPen(Qt::red);
painter.setFont(QFont("微软雅黑",28,QFont::Bold,true));
painter.drawText(0,50, QString("Hello World"));

 (15)Qt绘图(two)_第25张图片

// 将绘制字体固定在矩形区域内 (会自动换行)
painter.drawText(QRect(0,0,100,200), "Hello World Hello World!");

 (15)Qt绘图(two)_第26张图片

字体相关函数

// 设置字体
painter->setFont();
// 获取字体
painter->font();
// 获取字体信息
painter->fontInfo();
// 获取字体数据
painter->fontMetrics();

图片绘制

QPixmap

针对输出显示优化的图像绘制

 (15)Qt绘图(two)_第27张图片

 指定位置裁剪

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));                 // 裁剪区域

(15)Qt绘图(two)_第28张图片

drawPixmap(const QPoint &point, const QPixmap &pixmap, const QRect &source)

透明绘制

分别准备一张原码图和一张掩码图

(15)Qt绘图(two)_第29张图片

 (15)Qt绘图(two)_第30张图片

//掩码图和原图大小必须一致
//掩码图白色区域为透明,黑色区域为绘制
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);

(15)Qt绘图(two)_第31张图片

瓦片图绘制

// 函数原型
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));

(15)Qt绘图(two)_第32张图片

图像的保存

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");

(15)Qt绘图(two)_第33张图片

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

(15)Qt绘图(two)_第34张图片

碰撞检测

// 碰撞检测
#include 
#include 
#include 
#include 
#include 
#include 

// 碰撞检测
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"

(15)Qt绘图(two)_第35张图片

你可能感兴趣的:(Qt,qt,开发语言,c++)