Qt自绘控件之扇形统计图

2023-10-29

首先绘制区域扇形需要先注意一下几点:

  1. QPainter中绘制完整的圆等于5760(16 * 360),此处数值用于计算每一块扇形区域所显示的

  1. 需要了解一下扇形二等分线的计算方法

  1. 要注意做坐标原点转换

    /*此处为屏幕分辨率自适应*/
    const qreal ratioW = DesktopResize::GetInstance()->getWidthRatio();
    const qreal ratioH = DesktopResize::GetInstance()->getHeightRatio();
    const qreal ratioT = qMin(ratioW, ratioH);
    // 三角形和凸角必须指定为1/16度,即一个完整的圆等于5760(16 * 360)
    int circleArea = 5760;         
    // 设置圆弧显示区域    
    QRect rect(418 * ratioW, 340 * ratioH, 557  * ratioT, 557 * ratioT);
    // 圆半径
    int radius = rect.width() / 2;                  
    // 起始角度
    qreal startAngle = 0;
    // 当前绘制扇形所占角度
    qreal angle;
    //文字显示起始角度
    qreal textStartAngle = 0;
    // 文字显示角度
    qreal textAngle;
    // 需要统计的总数值
    int totalValue = 0;
    // _fanDataClassList为一个结构数据list,根据个人需要自行定义
    // 计算总数值
    for(int i = 0; i < _fanDataClassList.count(); i++)
    {
        totalValue += _fanDataClassList.at(i).value;
    }
    // 计算每个数值的扇形显示区域
    for(int i = 0; i < _fanDataClassList.count(); i++)
    {
        // 设置画笔颜色与画刷颜色保持一致,需要注意此处需要设设置画笔,否则会出现两个扇形之间显示有空白间隙
        QPen pen(_fanDataClassList.at(i).color, 1, Qt::SolidLine);
        painter->setPen(pen);
        // 设置画刷颜色与画笔保持一致
        painter->setBrush(_fanDataClassList.at(i).color);
        // 计算当前数值所占的百分比
        qreal persent = (double)_fanDataClassList.at(i).value / totalValue;
        // 根据百分比计算当前数值扇形尖角处所占角度的比例
        angle = circleArea * persent;
        // 通过path来获取当前绘制的扇形区域
        QPainterPath path;
        // 因圆心角需要在中位置来计算,将path起点移动到rect的中点位置
        path.moveTo(rect.center());
        // 创建一个占据给定矩形的弧,从指定的startAngle开始,逆时针扩展angle结束
        // 角度用角度来表示。顺时针弧线可以使用负角度指定。
        path.arcTo(rect, startAngle / 16, angle / 16);
        // 此处用来确定鼠标点击区域显示统计数据用,根据个人需要添加
        _pathValueMap.insert(i, path);
        // 绘制当前数值所占扇形区域
        painter->drawPath(path);
        // 如果不需要获取每块扇形的点击区域也可以直接使用drawPie绘制,就不需要使用path了
        //        painter->drawPie(rect, startAngle, angle);
        // 计算下一个扇形的起始角度
        startAngle += angle;
    }
    
    // 绘制每一块扇形区域的文字数目和占比统计
    painter->setBrush(Qt::NoBrush);
    for(int i=0; i < _fanDataClassList.count(); i++)
    {
        if(_fanDataClassList.at(i).value == 0)
            continue;
        // 同样先计算当前数值的占比
        qreal persent = (double)_fanDataClassList.at(i).value / totalValue;
        // 计算文字显示角度
        textAngle = circleArea * persent;
        //各个对应扇形二等分线的角度
        qreal abc = 3.14 * 2 * (double)(textStartAngle + textAngle / 2) / circleArea;       
        // 根据二等分线计算出当前扇形区域边缘的终点坐标
        qreal valueX = radius * qCos(abc) + radius + rect.x();
        qreal valueY = -radius * qSin(abc) + radius + rect.y();
        // 计算终点坐标相对于圆心的坐标用以标定文字的显示方向
        QPointF point = QPointF(valueX, valueY) - rect.center();

        int lineX = 0;
        int lineY = 0;
        int lineWidth = 0;
        int textX = 0;
        // 根据数学坐标系判断该点坐标所处象限
        if(point.x() > 0 && point.y() < 0)
        {
            lineX = 30  * ratioW;
            lineY = -30 * ratioH;
            lineWidth = 40 * ratioW;
            textX = valueX + lineX + lineWidth + 10 * ratioW;
        }
        else if(point.x() < 0 && point.y() < 0)
        {
            lineX = -30 * ratioW;
            lineY = -30 * ratioH;
            lineWidth = -40 * ratioW;
            textX = valueX + lineX + lineWidth - 250 * ratioW;
        }
        else if(point.x() < 0 && point.y() > 0)
        {
            lineX = -30 * ratioW;
            lineY = 30 * ratioH;
            lineWidth = -40 * ratioW;
            textX = valueX + lineX + lineWidth - 250 * ratioW;
        }
        else if(point.x() > 0 && point.y() > 0)
        {
            lineX = 30 * ratioW;
            lineY = 30 * ratioH;
            lineWidth = 40 * ratioW;
            textX = valueX + lineX + lineWidth + 10 * ratioW;
        }
        // 绘制二等分线和延迟线及文字下划线, 以下代码较为简单就不做注解了
        QPen pen(_fanDataClassList.at(i).color, 1, Qt::SolidLine);
        pen.setCapStyle(Qt::RoundCap);
        pen.setJoinStyle(Qt::RoundJoin);
        painter->setPen(pen);

        QVector<QPointF> points;
        points.push_back(QPointF(valueX, valueY));
        points.push_back(QPointF(valueX + lineX, valueY + lineY));
        points.push_back(QPointF(valueX + lineX + lineWidth, valueY + lineY));
        painter->drawPolyline(QPolygonF(points));

        QFont font = painter->font();
        font.setPixelSize(22 * ratioT);
        font.setWeight(50);
        font.setBold(true);
        painter->setFont(font);
        pen.setColor(Qt::black);
        painter->setPen(pen);
//        painter->drawText(valueX - 20, valueY, QString("%1%").arg( QString::number((persent * 100), 'f', 1)));
        if(i == 0)
        {
            painter->drawText(textX, valueY + lineY + 5 * ratioH, QString("正确率:100% %1人")
                              .arg(_fanDataClassList.at(i).value));
        }
        else if(i == 1)
        {
            painter->drawText(textX, valueY + lineY + 5 * ratioH, QString("正确率:90%-99% %1人")
                              .arg(_fanDataClassList.at(i).value));
        }
        else if(i == 2)
        {
            painter->drawText(textX, valueY + lineY + 5 * ratioH, QString("正确率:80%-89% %1人")
                              .arg(_fanDataClassList.at(i).value));
        }
        else if(i == 3)
        {
            painter->drawText(textX, valueY + lineY + 5 * ratioH, QString("正确率:60%-79% %1人")
                              .arg(_fanDataClassList.at(i).value));
        }
        else
        {
            painter->drawText(textX, valueY + lineY + 5 * ratioH, QString("正确率:0%-59% %1人")
                              .arg(_fanDataClassList.at(i).value));
        }

        textStartAngle += textAngle;
    }

效果如图:

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

Qt自绘控件之扇形统计图 的相关文章

  • 在 Qthread 中运行函数 - 应用程序将挂起

    我在 QT 内部线程方面遇到一些问题 include
  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk
  • QFileInfo::isWritable() 在 Windows 7 上具有完全权限时返回 false

    QFile file filePath QFileInfo fileInfo file file open QIODevice ReadWrite or WriteOnly if fileInfo isWritable Log error
  • 如何使用 ClangCodeModel 插件在 QtCreator 中设置 C++ 标准?

    抱歉 如果这是一个愚蠢的问题 但我已经尝试了几乎所有的方法 现在正在用头撞墙 问题是 带有 Clang 代码模型插件的 QtCreator 4 8 0 beta for Windows 解析我的项目 为 C 98 而实际上它是 C 17 但
  • QWinTaskbarProgress 不会显示

    我使用的是windows7和Qt5 3 0 我在 MainWindow 的构造函数中添加了以下内容 但任务栏上没有显示任何内容 我错过了什么 QWinTaskbarProgress pTaskbarProgress new QWinTask
  • 如何在 Qt simple 上解密/加密某些字符串(例如密码)

    这是我得到的 Qt SDK版本4 6 2 视窗XP 问题 我怎样才能简单地加密和简单地加密QString价值 我需要它能够将一些加密的字符串保存到 INI 文件中 并在重新打开应用程序后将字符串加密为正常的密码字符串值 PS 我正在寻找简单
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • QPainterPath::arcTo 上的角度如何解释?

    我正在开发图形编辑器的功能 在其中编辑弧线 当形状是椭圆形时 QPainterPath arcTo 的行为并不像我预期的那样 当它是一个圆圈时 它会按预期工作 下面的两张图片显示了结果 在第一种情况下 我创建了一个圆 然后将其转换为初始起始
  • 如何将flex和bison与Qt项目集成?

    我正在 git 源代码控制下使用 Qt4 制作 GUI 程序 Github页面 https github com vinayak garg dic sim 项目的一小部分需要扫描和解析 所以我想在项目中使用flex和bison 我能想到3种
  • 如何在不同的QT线程中创建一个窗口?

    我有一个应用程序 其中每个线程 主线程除外 都需要创建自己的窗口 我尝试创建一个线程然后调用this gt exec in the run功能 然而 在我接到那个电话之前我就收到了一个错误 ASSERT failure in QWidget
  • 如何在Qt3D中优化点云渲染

    我正在尝试使用 Qt3D 显示大型点云 20M pts 我第一次发现这个图书馆https github com MASKOR Qt3DPointcloudRenderer https github com MASKOR Qt3DPointc
  • 在 Windows 上从源代码构建 PhantomJS-2

    我正在尝试基于这些在 Windows 8 1 x64 上从源代码构建 PhantomJS 2 的开发版本指示 https github com ariya phantomjs wiki PhantomJS 2 但是我收到以下错误 mingw
  • 在 Windows 上以 QML 播放 RTSP 视频

    我正在尝试将 QML 中的 RTSP 流播放到视频标签中 如下所示 Repeater model 8 Video Layout fillWidth true Layout fillHeight true fillMode VideoOutp
  • MSVC C4100:“应用程序”:未引用的形式参数警告

    使用 MSVC 编译时 以下代码会生成 C4100 警告 这怎么可能 显然引用了 应用程序 class ApplicationInfo public QObject Q OBJECT public static void initializ
  • 当给定 100k 项时,QListView 需要很长时间才能更新

    我在读取文件时遇到问题 具体是我想制作一本小字典 在我需要阅读的文件中有这样的内容 a Ph P6 a snsr CA a b c fb Dj a b c book i BS A except B gate oOPa y a font kQ
  • PyQt:如何通过匿名代理使用网页

    这真让我抓狂 我想在 QWebPage 中显示一个 url 但我想通过匿名代理来实现 Code setting up the proxy proxy QNetworkProxy proxy setHostName 189 75 98 199
  • 如何从键盘为 QTableWidget 创建信号?

    我有一张桌子 可以通过左 右 上 下按钮在里面移动 现在 当我停留在某个单元格并按空格键时 我需要创建一个信号 该信号还应该带来该单元格的坐标 我尝试使用 QTableWidget 的标准信号 但它不起作用 我该如何解决这个问题 创建一个单
  • QtWebEngine Quicknano 在嵌入式 Linux 中没有声音

    我已将 QtWebEngine 编译到我的 i MX6 嵌入式设备中 当我尝试使用 Quicknanobrowser 播放 YouTube 视频时 视频会播放 但没有声音 事实上 当我尝试播放音频文件时没有声音hpr dogphilosop
  • 使用 QPrinter 打印第 x 页(共 y 页)

    我使用 qt 从 html 代码生成 pdf 文件 QTextDocument document new QTextDocument document gt setHtml htmlContent QPrinter printer QPri
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图

随机推荐

  • 解决Unity3D提示‘Newtonsoft‘could not be found

    原因 Newtonsoft是一个C 中使用Json来进行数据的交互的程序集 1 与Unity自带的插件版本有关系 不能识别到包中的Newtonsoft 2 未导入Newtonsoft dll程序集 提醒你的代码路径 error CS0246
  • win10设置小鹤双拼

    可以使用注册表双击执行或者按步骤操作 Windows Registry Editor Version 5 00 HKEY CURRENT USER Software Microsoft InputMethod Settings CHS En
  • 音视频基础之封装格式与音视频同步

    封装格式的概念 封装格式 也叫容器 就是将已经编码压缩好的视频流 音频流及字幕按照一定的方案放到一个文件中 便于播放软件播放 一般来说 视频文件的后缀名就是它的封装格式 封装的格式不一样 后缀名也就不一样 比如 同样的陷可以做成饺子也可以做
  • php 定义float,MySql中float类型含义及参数详解

    php 定义float MySql中float类型含义及参数详解 float表示浮点数 通俗点来说的话 我们可以简单理解为小数 参数有两个 M表示精度 表示浮点数的位数 D表示标度 表示小数位数 M位数不包括小数点位数 举例 float 6
  • Excel如何将引用的sheet名称全部替换。

    一 设置引用sheet名称 例如为星期2 输入公式 引用A2行内容 星期2 A2 符号为固定单元格 二 将表格3星期3的内容引用到星期一表格中 三 将星期3内容引用到星期一 星期3 A2 如何将星期2全部换成星期3呢 四 将星期1的复制到新
  • 智能制造MES系统的主要内容有哪些?系统有什么作用?

    制造企业非常关注实现生产过程中的实时采集 提高生产排产的效率 实现制造过程的追溯 提升工人与设备的绩效 保证产品质量等问题 调研数据显示 92 的企业渴望加强对生产过程的控制 大多数制造企业已经逐渐清醒地认识到生产技术领先和制造过程管理高效
  • Linux操作系统常见面试题(持续更新)

    1 熟悉命令netstat tcpdump ipcs ipcrm netstat 检查网络状态 tcpdump 截获数据包 ipcs 检查共享内存 ipcrm 解除共享内存 2 共享内存段被映射进进程空间之后 存在于进程空间的什么位置 共享
  • uni-app在真机调试下兼容ethers的方法

    目录 一 安装ethers 二 renderjs 三 注意事项 uni app开发跨平台应用程序 项目搭建主要前端框是Uni app Vue3 TS Vite 项目搭建参考文章Uni app Vue3 TS Vite 创建项目 Hbuild
  • tac_plus安装和配置

    安装 将 http download csdn net detail wingking84 5814131 解压 PROJECTS放到 root下 进入PROJECTS然后执行 make make install 配置 将参考配置文件 ht
  • 英国加密货币流动性提供商获得金融监管机构批准

    点击上方 蓝色字 可关注我们 暴走时评 根据金融行为监管局 FCA 的注册记录 英国加密货币流动性创业公司B2C2 OTC Ltd 已于1月30日获得该国FCA的批准 B2C2将提供电子场外交易 OTC 可以向合格交易方和专业客户提供差价合
  • CUDA——SM中warp调度器调度机制&&访存延迟隐藏

    SM中warp调度器调度机制 访存延迟隐藏 核函数中并不是所有线程一起启动执行的 核函数的执行是以线程束 warps 作为单位 warps的执行由warp调度器进行调度 一个调度器只能调度一个warp去执行指令 一个warp里的所有线程几乎
  • Symbol 'ANDROID_LOG_DEBUG' could not be resolved

    调试JNI代码的时候 加入了调试函数 include
  • 如何构造LL(1)文法预测分析表

    这类题型也经常在考试中出现 一般是与判断是否为LL 1 文法放在一起进行考察 这类题目该怎么去做呢 1 求出每个非终结符的FIRST集和FOLLOW集 在上一篇文章中已经详细介绍 2 构造预测分析表 横坐标是所有的非终结符 纵坐标是所有的终
  • 【计算机视觉

    文章目录 一 STPLS3D 二 DigestPath 三 ImageNet S ImageNet Semantic Segmentation 四 OpenEDS 五 RELLIS 3D 六 SUIM Segmentation of Und
  • React解密:React Hooks函数之useEffect和useLayoutEffect

    useEffect是react hooks的又一个重要的hooks函数 Effect hooks允许你在组件中执行副作用操作 数据获取 设置订阅以及手动更改 React 组件中的 DOM 都属于副作用 不管你知不知道这些操作 或是 副作用
  • js事件的绑定方式

    我们现在绑定的事件都是 onxxxx的方式 这个是DOM0级的事件绑定方式 注 这个方式不是很好 弊端 一旦写了第二个事件 那么第一个就会被覆盖 案例 var oDiv document querySelector div oDiv onc
  • gethup.sh

    docker exec it geth cluster1 bin bash geth datadir data0 networkid 779977 console root 85547cf26bca ethutil cat gethup s
  • 某易云音乐JS逆向案例

    某易云音乐参数破解 目标 aHR0cHM6Ly9tdXNpYy4xNjMuY29tLyMvc2VhcmNoL20vP3M9JUU2JTg4JTkwJUU5JTgzJUJEJnR5cGU9MQ 某易云音乐是大家喜爱的音乐平台 有小伙伴问我 这
  • 网关的理解

    一 什么是网关 网关 Gateway 又称网间连接器 协议转换器 网关在传输层上以实现网络互连 是最复杂的网络互连设备 仅用于两个高层协议不同的网络互连 二 如何来理解网关 大家都知道 从一个房间走到另一个房间 必然要经过一扇门 同样 从一
  • Qt自绘控件之扇形统计图

    首先绘制区域扇形需要先注意一下几点 QPainter中绘制完整的圆等于5760 16 360 此处数值用于计算每一块扇形区域所显示的 需要了解一下扇形二等分线的计算方法 要注意做坐标原点转换 此处为屏幕分辨率自适应 const qreal