(15)Qt绘图(two)

news2024/12/25 1:11:40

目录

坐标变换

平移坐标轴

缩放坐标轴

旋转坐标轴

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

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"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/845902.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【雕爷学编程】Arduino动手做(195)---HT16k33 矩阵 8*8点阵屏模块2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

链表——LinkedList类的概述和实现

LinkedList类 1.1LinkedList类概述 LinkedList类底层是基于双向链表结构实现的&#xff0c;不同于ArrayList类和Vector类是基于数组实现的&#xff1b;LinkedList类是非线程安全的&#xff1b;LinkedList类元素允许为null&#xff0c;允许重复元素&#xff1b;LinkedList类插…

Python识别抖音Tiktok、巨量引擎滑块验证码识别

由于最近比较忙&#xff0c;所以本周搞了一个相对简单的验证码&#xff0c;就是抖音Tiktok的滑块验证码&#xff0c;这也是接到客户的一个需求。这种验证码通常在电脑端登录抖音、巨量引擎的的时候出现。 首先看一下最终的效果&#xff1a; 验证码识别过程 1、利用爬虫采集图…

CS录屏教程,录制游戏需要注意哪些方面?

​最近有个CS手游的玩家小伙伴咨询想要做一些游戏视频录制&#xff0c;但是不知道有哪些好用的工具来使用&#xff0c;对于游戏录制我们其实是需要注意一些事项的&#xff0c;想要观众的观感上比较好就需要把握好视频的帧率等问题&#xff0c;下面我们就来看看录制方法和需要注…

Vue3自定义简单的Swiper滑动组件-触控板滑动鼠标滑动左右箭头滑动-demo

代码实现了一个基本的滑动功能&#xff0c;通过鼠标按下、鼠标松开和鼠标移动事件来监听滑动操作。 具体实现逻辑如下&#xff1a; 在 onMounted 钩子函数中&#xff0c;我们为滚动容器添加了三个事件监听器&#xff1a;mousedown 事件&#xff1a;当鼠标按下时&#xff0c;设置…

windows环境下编译OpenJDK12

环境&#xff1a;Windows11 目录&#xff1a; 1、下载OpenJDK12源码 下载地址&#xff1a; https://hg.openjdk.org/jdk/jdk12 点击zip下载到本地。 解压到本地。 Tip&#xff1a;注意本地路径中最好不要包含中文或空格。 2、阅读一遍doc/building.html 如果只是想构建J…

C++11 新特性 ---- 原始字面量

一、原始字面量 R “xxx(原始字符串)xxx”&#xff0c;其中&#xff08;&#xff09;两边的字符串可以省略。 #include <iostream> #include <string> using namespace std; int main() {string str1 R"(D:\hello\heheda\test.txt)";string str2 R&q…

dfs之卒的遍历

题面 题目描述 在一张nm 的棋盘上&#xff08;如 6 行 7 列&#xff09;的最左上角(1,1) 的位置有一个卒。该卒只能向下或者向右走&#xff0c;且卒采取的策略是先向下&#xff0c;下边走到头就向右&#xff0c;请问从(1,1) 点走到 (n,m) 点可以怎样走&#xff0c;输出这些走法…

TM4C123库函数学习(1)--- 点亮LED+TM4C123的ROM函数简介+keil开发环境搭建

前言 &#xff08;1&#xff09; 首先&#xff0c;我们需要知道TM4C123是M4的内核。对于绝大多数人而言&#xff0c;入门都是学习STM32F103&#xff0c;这款芯片是采用的M3的内核。所以想必各位对M3内核还是有一定的了解。M4内核就是M3内核的升级版本&#xff0c;他继承了M3的的…

pka 预测汇总

汇总内容来自 Open-Source Machine Learning in Computational Chemistry 中表格涉及的内容 文章目录 1.DeepKa2.Machine learning meets pKa 1.DeepKa 预测蛋白质的 pka&#xff0c;文章是 Basis for Accurate Protein p Ka Prediction with Machine Learning 和 Protein p…

web-csrf

目录 CSRF与XSS的区别&#xff1a; get请求 原理&#xff1a; pikachu为例 post请求 pikachu为例 CSRF与XSS的区别&#xff1a; CSRF是借用户的权限完成攻击&#xff0c;攻击者并没有拿到用户的权限&#xff0c;而XSS是直接盗取到了用户的权限 get请求 原理&#xff1a;…

20230807在WIN10下使用python3将TXT文件转换为DOCX(在UTF8编码下转换为DOCX有多一行的瑕疵)

20230807在WIN10下使用python3将TXT文件转换为DOCX&#xff08;在UTF8编码下转换为DOCX有多一行的瑕疵&#xff09; 2023/8/7 12:58 https://translate.google.com/?slen&tlzh-CN&opdocs 缘起&#xff0c;由于google的文档翻译不支持SRT/TXT格式的字幕&#xff0c;因此…

利用Arthas+APM监控进行Java性能深度定位

大家可能都用过APM监控&#xff0c;包括开源的Skywalking、商用的卓豪&#xff08;ZOHO&#xff09;ManageEngine APM应用性能监控、以及云监控产品如听云&#xff08;Server监控&#xff09;&#xff0c;这些APM监控产品大大方便了我们实时监控应用性能&#xff0c;并实现性能…

04-6_Qt 5.9 C++开发指南_QListWidget和QToolButton

文章目录 1. 实例简介2. 源码2.1 混合式界面设计2.2 mainwindow.h2.3 mainwindow.cpp 1. 实例简介 Qt 中用于项 (Item)处理的组件有两类&#xff0c;一类是 Item Views&#xff0c;包括 QListView、QTreeView、QTableView、QColumnView 等;另一类是 Item Widgets&#xff0c;包…

用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项

一、实际工作中需要对转换选项细化内容 在昨天我们实现了最简单的半角字符和全角字符相互转换功能&#xff0c;就是将英文字母、阿拉伯数字、标点符号、空格全部进行转换。 在实际工作中&#xff0c;我们有时只想英文字母、阿拉伯数字、标点符号、空格之中的一两类进行转换&a…

FTP Server(二)

问题 使用Centos8通过命令行登录FTP服务器后发现乱码&#xff0c;无法显示中文 原因 FTP服务器是windows系统使用的是GBK编码&#xff0c;大多数Linux版本默认使用的是UTF-8 解决 在家目录下新建编辑 .lftprc 文件 [rootwenzi ~]#pwd /root [rootwenzi ~]#vim .lftprc debu…

狂神说-通俗易懂的23种设计模式

狂神说-通俗易懂的23种设计模式 文章目录 1、设计模式概述2、OOP七大原则4、工厂模式5、抽象工厂模式6、建造者模式7、原型模式8、适配器模式9、桥接模式10、静态代理模式11、静态代理再理解12、动态代理详解 1、设计模式概述 设计模式的基本要素&#xff1a; 1、模式名称 2、…

以太网DHCP协议(十)

目录 一、工作原理 二、DHCP报文 2.1 DHCP报文类型 2.2 DHCP报文格式 当网络内部的主机设备数量过多是&#xff0c;IP地址的手动设置是一件非常繁琐的事情。为了实现自动设置IP地址、统一管理IP地址分配&#xff0c;TCPIP协议栈中引入了DHCP协议。 一、工作原理 使用DHCP之…

2022 robocom 世界机器人开发者大赛-本科组(国赛)

RC-u1 智能红绿灯 题目描述&#xff1a; RC-u1 智能红绿灯 为了最大化通行效率同时照顾老年人穿行马路&#xff0c;在某养老社区前&#xff0c;某科技公司设置了一个智能红绿灯。 这个红绿灯是这样设计的&#xff1a; 路的两旁设置了一个按钮&#xff0c;老年人希望通行马路时会…

C语言预处理命令 #error 学习

#error命令是C/C语言的预处理命令之一&#xff0c;当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息。 如下代码输出数字1000&#xff0c;如果加了 #error&#xff0c;构建时不会通过&#xff0c;提示出错如下&#xff1b; 这可能在大型项目中比较有用&am…