(14)Qt绘图(one)

简介: 本文介绍了在Qt中使用QPainter进行绘图的基础操作,包括如何指定绘图设备、使用QPen和QBrush设置线条和填充样式、绘制不同样式的线条和形状,以及如何实现纹理填充和渐变填充等效果。

绘图的基本使用

只要是在QWidget类及其子类中绘图,必须把绘图的操作放到重绘事件

// 绘图事件
void Widget::paintEvent(QPaintEvent *ev)
{
    // 定义画家
    QPainter painter(this);
    // 绘制线条
    painter.drawLine(10, 10, 100, 100);
}

绘图的流程

  1. 创建栈区画家(QPainter)对象(不需要使用堆区内存,需要使用时再重新定义即可)

  2. 指定绘图设备(一般直接指定在需要绘图的窗口上即可)

  3. 创建画刷或画笔对象(画笔QPen或画刷QBrush

  4. 将画笔或者画刷交给画家

  5. 绘制图形

指定绘图设备的两种方式

// 直接使用QPainter的构造函数指定
QPainter painter(this);
// 使用成员函数指定
QPainter painter;
painter.begin(this);
// 在begin与end之间进行绘图
painter.end();

QPen的使用

线条样式

QPainter painter(this);

QPen pen;
pen.setStyle(Qt::PenStyle::DashDotDotLine);
pen.setWidth(3);
pen.setColor(Qt::red);
painter.setPen(pen);

painter.drawLine(10, 10, 100, 100);

QPainter painter(this);
for(int i = 0; i <= 6; i++)
{
    QPen pen;
    pen.setStyle(Qt::PenStyle(i));
    pen.setWidth(3);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawLine(i * 100, 0, i *100 + 100, 100);
}

笔帽样式

QPainter painter(this);
// 笔帽样式
Qt::PenCapStyle s[] = {Qt::PenCapStyle::SquareCap,
                       Qt::PenCapStyle::FlatCap,
                       Qt::PenCapStyle::RoundCap};
for(int i = 0; i <= 6; i++)
{
    QPen pen;
    pen.setStyle(Qt::PenStyle(i));
    pen.setWidth(30);
    pen.setColor(Qt::red);
    // 设置笔帽样式
    pen.setCapStyle(s[i % 3]);
    painter.setPen(pen);
    // 设置抗锯齿
    painter.setRenderHint(QPainter::RenderHint::Antialiasing);
    painter.drawLine(i * 100, 0, i *100 + 100, 100);
}

线条连接样式

QPainter painter(this);
// 设置抗锯齿
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
// 连接样式
Qt::PenJoinStyle s[] = {Qt::MiterJoin,
                        Qt::BevelJoin,
                        Qt::RoundJoin,
                        Qt::SvgMiterJoin,
                        Qt::MPenJoinStyle};
for(int i = 0; i < 5; i++)
{
    QPen pen;
    pen.setStyle(Qt::PenStyle::SolidLine);
    pen.setWidth(5);
    pen.setColor(Qt::red);
    // 设置笔帽样式
    pen.setJoinStyle(s[i]);
    painter.setPen(pen);
    QPoint points[] = {
  {20 + i * 100, 30},
                       {50 + i * 100, 60},
                       {100 + i * 100, 10}};
    painter.drawPolygon(points, 3);
}

QBrush的使用

画刷样式设置

Qt::BrushStyle s[] = {Qt::BrushStyle::NoBrush,
                          Qt::BrushStyle::SolidPattern,
                          Qt::BrushStyle::Dense1Pattern,
                          Qt::BrushStyle::Dense2Pattern,
                          Qt::BrushStyle::Dense3Pattern,
                          Qt::BrushStyle::Dense4Pattern,
                          Qt::BrushStyle::Dense5Pattern,
                          Qt::BrushStyle::Dense6Pattern,
                          Qt::BrushStyle::Dense7Pattern,
                          Qt::BrushStyle::HorPattern,
                          Qt::BrushStyle::VerPattern,
                          Qt::BrushStyle::CrossPattern,
                          Qt::BrushStyle::BDiagPattern,
                          Qt::BrushStyle::FDiagPattern,
                          Qt::BrushStyle::DiagCrossPattern,
                          Qt::BrushStyle::LinearGradientPattern,
                          Qt::BrushStyle::ConicalGradientPattern,
                          Qt::BrushStyle::RadialGradientPattern
                          };
int y = 0;
int col = 0;
for(int i = 0; i < 18; i++)
{
    QBrush brush(s[i]);
    // 注意参数3跟4是矩形的宽高,而不是右下角坐标
    painter.fillRect(col++ * 150, y * 150, 150, 150, brush);
    if((i + 1) % 5 == 0) y++, col = 0;
}

Qt中的随机数的使用

// 头文件
#include <qrandom.h>
// 32位随机数生成
qInfo() << QRandomGenerator::global()->bounded(0, 256);
// 64位随机数生成
qInfo() << QRandomGenerator64::global()->bounded(0, 256);

// 使用宏简化使用方式
#define random(min,max) QRandomGenerator64::global()->bounded(min, max)

填充规则

纹理填充(图片填充)

QBrush brush(QPixmap(":/aaa.png"));
painter.setBrush(brush);
painter.drawRect(0, 0, 480, 460);

渐变填充

线性渐变

QLinearGradient gra(0,0,400,400);  // 指定两个点,控制渐变的方向
// 插值进行颜色的渐变,插值范围[0,1]
gra.setColorAt(0, Qt::red);
gra.setColorAt(1, Qt::green);

painter.setBrush(QBrush(gra));
// 绘制一个矩形
painter.drawEllipse(0,0,400,400);

径向渐变

QRadialGradient gra(200,200,200); // 圆心 半径

gra.setColorAt(0, 0xfad0c4);      // 帮助文档有网站可以查看颜色值
gra.setColorAt(1, 0xffd1ff);

painter.setBrush(gra);
painter.drawRect(0,0,400,400);

查看Qt帮助文档预定义的渐变色以及相关网站

锥形渐变

QConicalGradient gra(200,200,0); // 圆心 开始角度

gra.setColorAt(0, Qt::red);
gra.setColorAt(0.5, Qt::blue);
gra.setColorAt(1, Qt::green);

painter.setBrush(gra);
painter.drawEllipse(0,0,400,400);

渐变区域之外的渐变样式(以线性渐变为例)

// 默认
QLinearGradient gra(0,0,200,200);
gra.setColorAt(0, Qt::red);
gra.setColorAt(1, Qt::green);

gra.setSpread(QGradient::Spread::PadSpread); // 默认

painter.setBrush(gra);
painter.drawRect(0,0,200,200);
painter.drawRect(200,200,200,200);

QLinearGradient gra(0,0,200,200);
gra.setColorAt(0, Qt::red);
gra.setColorAt(1, Qt::green);

gra.setSpread(QGradient::Spread::RepeatSpread);  // 重复渐变

painter.setBrush(gra);
painter.drawRect(0,0,200,200);
painter.drawRect(200,200,200,200);

QLinearGradient gra(0,0,200,200);
gra.setColorAt(0, Qt::red);
gra.setColorAt(1, Qt::green);

gra.setSpread(QGradient::Spread::ReflectSpread);        // 反向渐变

painter.setBrush(gra);
painter.drawRect(0,0,200,200);
painter.drawRect(200,200,200,200);

预定义渐变色的使用

// 预定义渐变方式的使用
QGradient gra(QGradient::Preset::AmyCrisp);

painter.setBrush(gra);
painter.drawRect(0,0,width(),height());

坐标模式的使用

对象模式的使用

//设置坐标模式后不加渐变方向(对象模式就是使用的对象的开始位置到结束位置(0, 0 200, 200))
// 坐标模式的使用
QLinearGradient gra;            // 设置坐标模式后可不加渐变方向
gra.setColorAt(0, 0x89f7fe);
gra.setColorAt(1, 0x66a6ff);

gra.setCoordinateMode(QGradient::ObjectMode);   // 设置坐标模式为对象模式
painter.setBrush(gra);

painter.drawEllipse(0,0,200,200);
painter.drawEllipse(200,0,200,200);
painter.drawEllipse(400,0,200,200);

对象模式渐变方向的设置

// 设置为对象模式后,渐变方式变为(0,0,1,1) 左上 -> 右下
QLinearGradient gra(0,0,0,1);     // 左上 -> 左下        
gra.setColorAt(0, 0x89f7fe);
gra.setColorAt(1, 0x66a6ff);

gra.setCoordinateMode(QGradient::ObjectMode);   // 设置坐标模式为对象模式
painter.setBrush(gra);

painter.drawEllipse(0,0,200,200);
painter.drawEllipse(200,0,200,200);
painter.drawEllipse(400,0,200,200);

相关文章
|
28天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
4天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
442 17
|
7天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
20天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
7天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
380 2
|
22天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
24天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2600 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
6天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
289 2
|
4天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
106 65
|
24天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1582 17
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码