31 Qt 之绘图之绘制一个漂亮的圆及圆弧

2023-11-10

一、圆形

经常地,我们会在网上看到一些列的抽奖活动,里面就有圆盘抽奖,是不是有点手痒了O(∩_∩)O~

效果

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    int radius = 150;
    int arcHeight = 30;

    // >> 1(右移1位)相当于width() / 2
    painter.translate(width() >> 1, height() >> 1);

    /**
     * 参数二:半径
     * 参数三:开始的角度
     * 参数四:指扫取的角度-顺时针(360度 / 8 = 45度)
     * 参数五:圆环的高度
     * 参数六:填充色
    **/
    gradientArc(&painter, radius, 0,  45, arcHeight, qRgb(200, 200, 0));
    gradientArc(&painter, radius, 45, 45, arcHeight, qRgb(200, 0, 200));
    gradientArc(&painter, radius, 90, 45, arcHeight, qRgb(0, 200, 200));
    gradientArc(&painter, radius, 135, 45, arcHeight, qRgb(200, 0, 0));
    gradientArc(&painter, radius, 225, 45, arcHeight, qRgb(0, 200, 0));
    gradientArc(&painter, radius, 180, 45, arcHeight, qRgb(0, 0, 200));
    gradientArc(&painter, radius, 270, 45, arcHeight, qRgb(0, 0, 0));
    gradientArc(&painter, radius, 315, 45, arcHeight, qRgb(150, 150, 150));
}

void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
{
    // 渐变色
    QRadialGradient gradient(0, 0, radius);
    gradient.setColorAt(0, Qt::white);
    gradient.setColorAt(1.0, color);
    painter->setBrush(gradient);

    // << 1(左移1位)相当于radius*2 即:150*2=300
    //QRectF(-150, -150, 300, 300)
    QRectF rect(-radius, -radius, radius << 1, radius << 1);
    QPainterPath path;
    path.arcTo(rect, startAngle, angleLength);

    painter->setPen(Qt::NoPen);
    painter->drawPath(path);
}

二、弧形

我们可以在之前的基础上加一些处理,从而实现一个圆弧。


效果

void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
{
    // 渐变色
    QRadialGradient gradient(0, 0, radius);
    gradient.setColorAt(0, Qt::white);
    gradient.setColorAt(1.0, color);
    painter->setBrush(gradient);

    // << 1(左移1位)相当于radius*2 即:150*2=300
    //QRectF(-150, -150, 300, 300)
    QRectF rect(-radius, -radius, radius << 1, radius << 1);
    QPainterPath path;
    path.arcTo(rect, startAngle, angleLength);

    // QRectF(-120, -120, 240, 240)
    QPainterPath subPath;
    subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));

    // path为扇形 subPath为椭圆
    path -= subPath;

    painter->setPen(Qt::NoPen);
    painter->drawPath(path);
}

添加文本

可以通过QPainterPath的addText()来添加文本。

void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
{
    // 渐变色
    QRadialGradient gradient(0, 0, radius);
    gradient.setColorAt(0, Qt::white);
    gradient.setColorAt(1.0, color);
    painter->setBrush(gradient);

    // << 1(左移1位)相当于radius*2 即:150*2=300
    //QRectF(-150, -150, 300, 300)
    QRectF rect(-radius, -radius, radius << 1, radius << 1);
    QPainterPath path;
    path.arcTo(rect, startAngle, angleLength);

    // QRectF(-120, -120, 240, 240)
    QPainterPath subPath;
    subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));

    // path为扇形 subPath为椭圆
    path -= subPath;

    QFont font;
    font.setFamily("Microsoft YaHei");
    font.setPointSize(14);

    painter->setPen(Qt::NoPen);
    path.addText(path.pointAtPercent(0.5), font, QStringLiteral("一去丶二三里"));
    painter->drawPath(path);
}

添加旋转效果

我们对前面的圆盘进行强化,添加一个旋转效果。当然,常见的抽奖圆盘旋转的是指针,而我们下面实现的是对圆盘的旋转,如果你要实现一个抽奖转盘,那么可以再扩展。

// 利用定时器,定时变换角度,进行旋转。
QTimer *pTimer = new QTimer(this);
pTimer->setInterval(100);
connect(pTimer, SIGNAL(timeout()), this, SLOT(updatePaint()));
pTimer->start();

// 改变角度,进行旋转
void MainWindow::updatePaint()
{
    m_nRotationAngle++;
    if (m_nRotationAngle > 360)
        m_nRotationAngle = 0;
    update();
}

然后,只需要在绘图事件中添加简单的一行代码即可:

void MainWindow::paintEvent(QPaintEvent *)
{
    ...
    // 旋转
    painter.rotate(m_nRotationAngle);
    ...
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

31 Qt 之绘图之绘制一个漂亮的圆及圆弧 的相关文章

随机推荐

  • linux下对java程序生成dump文件

    1 首先 java程序启动在linux 怎么生成dump文件 1 第一步 首先你需要得到java程序的PID 最简单的方法使用如下命令 ps ef grep java 或者如果是docker启动的 springboot服务 也可以使用本命令
  • Android 基础知识4-3.11 Adapter(适配器)详解

    一 简介 Adapter是连接后端数据和前端显示的适配器接口 是数据和UI View 之间一个重要的纽带 在常见的View ListView GridView 等地方都需要用到Adapter 如下图直观的表达了Data Adapter Vi
  • 在区块链上开发可更新的智能合约

    由于区块链不可篡改的特性 智能合约一旦部署在区块链上 其执行的逻辑就无法再更改 长期来看 这个重要的特性反而限制了智能合约的弹性和发展 接下来要介绍如何设计及部署合约才能让合约在需要时可以更新 但这里的更新意思不是修改已经部署的合约 而是部
  • 【一网打尽】独立重复事件——常见概率分布

    文章目录 定义 伯努利 Bernouli 试验 n重伯努利试验 伯努利过程 泊松 Poisson 过程 概率分布的意义 0 1分布 伯努利分布 二项 Binomial 分布 负二项 NegativeBinomial 分布 几何 Geomet
  • 区块链的数据结构(一)——区块、链

    区块 区块 block 由区块头 block header 和交易列表 transaction list tx list 组成 block之间通过block header的hash连接成了一个链表结构 但这个链表不同于普通链表 1 bloc
  • JAVA根据PDF文件生成图片

    PDF文件生成图片 实现功能 根据上传的PDF文件 生成图片文件 单页PDF 生成图片文件 多页PDF 则生成zip压缩包 一 文件生成效果 二 引入所需maven依赖 项目采用springboot框架
  • python学习1.2字符串

    一 给变量赋值字符串的时候 要用引号引起来 可以用单引号或者双引号 1 输入 message hello world print message 输出 hello world 2 输入 message hello world print m
  • Java操作ElasticSearch相关内容

    Java连接ES 创建Maven工程 导入依赖
  • 常用遥感SIF和GPP数据集

    一 综述文章 总结一下数据和文章 害怕时间久了忘了 前两篇介绍了SIF 最后一篇介绍了光合作用 1 Remote sensing of solar induced chlorophyll fluorescence SIF in vegeta
  • 【车辆检测】基于背景差分法实现道路行驶车辆检测附matlab代码

    1 简介 该方法的基本思想是 将采集到的车辆图像的每一帧都与一个不含运动车辆的静止参考帧做差值运算 从而突出目标图像 通过分析与处理对车辆计数 其优点是算法简单 处理速度快 且差分结果能直接反应运动目标的位置 形状以及大小等 实用性较强 其
  • css flex布局 —— 容器属性 align-content

    align content 属性定义了多根轴线的对齐方式 如果项目只有一根轴线 该属性不起作用 如果只有一根轴线 align content 几乎等同于 align items 容器属性 align content 生效的条件是 必须显式的
  • 高校校园网使用的认证客户端常见故障自查- 神州数码客户端

    神州数码客户端常见故障自查 一 客户端认证成功前故障 1 接上网线后网卡灯不亮 确定自己电脑网卡带灯 注 测试期间最好是不要接交换机 直接接墙上端口 参考方案 A 更换网线 B 如确认是端口故障 则请致电网络中心报修等待人过来维修 2 如果
  • (每日一练)MATLAB生成斐波那契数和数列

    今天 我学习的内容是利用MATLAB生成斐波那契数 先来介绍一下 斐波那契数列最初是用来解决兔子问题的 问题如下 一个人把一对兔子放在一个四面被墙包围的地方 假设每对兔子每个月都生一对新兔子 不 考虑伦理问题 那么一年可以从这对兔子中生产多
  • C/C++中__builtin_popcount()的使用及原理

    这个函数功能 返回输入数据中 二进制中 1 的个数 对于不同的使用类型 可以采用采用以下函数 builtin popcount int builtin popcountl long int builtin popcountll long l
  • Python列表推导式

    列表推导式 列表推导式使用非常简洁的方式来快速生成满足特定需求的列表 代码具有非常强的可读性 语法形式为 expression for expr1 in sequence1 if condition1 for expr2 in sequen
  • nginx之头部变量x_forwarded_for

    proxy add x forwarded for变量包含客户端请求头中的 X Forwarded For 与 remote addr两部分 他们之间用逗号分开 举个例子 有一个web应用 在它之前通过了2个nginx转发 即用户访问该we
  • P1518 [USACO2.4]两只塔姆沃斯牛 The Tamworth Two

    题目描述 两只牛逃跑到了森林里 Farmer John 开始用他的专家技术追捕这两头牛 你的任务是模拟他们的行为 牛和 John 追击在10 10 的平面网格内进行 一个格子可以是 一个障碍物 两头牛 它们总在一起 或者 Farmer Jo
  • 如何有效使用渲染农场?防止渲染出错的7个方法!

    如何使用渲染农场 又如何有效地使用渲染农场 使用云渲染农场时出错怎么办 众所周知我们可以在任意的笔记本或者终端PC上面来创作 3ds Max 场景 但是实际渲染是这样吗 其实不然 这其中的差距不是一星半点 只能说很可能会有两种不同的呈现 而
  • HTML+CSS+JS列表式视频播放页面

    HTML CSS JS列表式视频播放页面 无插件 应该没有 效果图 html
  • 31 Qt 之绘图之绘制一个漂亮的圆及圆弧

    一 圆形 经常地 我们会在网上看到一些列的抽奖活动 里面就有圆盘抽奖 是不是有点手痒了O O 效果 void MainWindow paintEvent QPaintEvent QPainter painter this painter s