绘制饼图详细过程

QtCharts绘制饼图

说明:qcustomplot模块没有绘制饼图的接口和模块,所以用Qt官方自带的QtCharts进行绘制。绘制出来还挺美观。

1 模块导入

QT       += charts
QT_BEGIN_NAMESPACE

以上这两行代码必须得加

2 总体代码

  • widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtCharts>
#include <QChartView>
#include "qcustomplot.h"
#include <QTimer>
#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
QT_CHARTS_USE_NAMESPACE
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public:void paintPie(QChartView *chartView);private:Ui::Widget *ui;QTimer *timer;
};
#endif // WIDGET_H
  • widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);paintPie(ui->graphicsView);timer = new QTimer(this);connect(timer, &QTimer::timeout, this,[this](){// 预定义的类别名称数组static const QStringList categoryNames = {"Search Engine","Direct","Email","Union Ads","Video Ads"};QPieSeries *series = static_cast<QPieSeries *>(ui->graphicsView->chart()->series().at(0));QList<QPieSlice*> slices = series->slices();if (slices.size() >= 5){slices[0]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[1]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[2]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[3]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[4]->setValue(QRandomGenerator::global()->bounded(10, 100));}for (int i = 0; i < slices.size(); i++){qreal percent = (slices[i]->value() / series->sum()) * 100.0;
//            修改了这句代码,slice->label()会获取标签值,然后在标签值后不断追加数据
//            label = QString("%1\n%2%").arg(slice->label()).arg(percent, 0, 'f', 1);QString label = QString("%1\n%2%").arg(categoryNames[i]).arg(percent, 0, 'f', 1);slices[i]->setLabel(label);slices[i]->setLabelVisible(true);slices[i]->setLabelArmLengthFactor(0.05);slices[i]->setLabelPosition(QPieSlice::LabelOutside);}});timer->start(1000);
}Widget::~Widget()
{delete ui;
}void Widget::paintPie(QChartView *chartView)
{// 创建饼图对象QPieSeries *series = new QPieSeries();series->setHoleSize(0.35);  // 空心圆大小(0-1)series->setPieSize(0.7);     // 饼图相对视图的大小// 创建Chart画布QChart *chart = new QChart();chartView->setBackgroundBrush(QBrush(QColor(Qt::black)));chart->setBackgroundBrush(QBrush(QColor(Qt::black)));chart->addSeries(series);chart->setAnimationOptions(QChart::AllAnimations); // 设置显示时的动画效果chart->setTitle("系统CPU利用率");chart->setTitleFont(QFont("Arial", 14, QFont::Bold));// 将参数设置到画布chartView->setChart(chart);chartView->setRenderHint(QPainter::Antialiasing);chartView->chart()->setTheme(QChart::ChartTheme(0));chartView->setRubberBand(QChartView::RectangleRubberBand);  // 矩形缩放// 添加数据切片QPieSlice *slice1 = series->append("Search Engine", 1048);QPieSlice *slice2 = series->append("Direct", 735);QPieSlice *slice3 = series->append("Email", 580);QPieSlice *slice4 = series->append("Union Ads", 484);QPieSlice *slice5 = series->append("Video Ads", 300);// 配置每个切片的样式slice1->setColor(QColor(92, 123, 217));slice2->setColor(QColor(159, 224, 128));slice3->setColor(QColor(255, 220, 96));slice4->setColor(QColor(255, 112, 112));slice5->setColor(QColor(126, 211, 244));// 设置标签格式:显示百分比和名称for (auto slice : series->slices()) {qreal percent = (slice->value() / series->sum()) * 100.0;QString label = QString("%1\n%2%").arg(slice->label()).arg(percent, 0, 'f', 1);slice->setLabel(label);slice->setLabelVisible(true);slice->setLabelArmLengthFactor(0.05);  // 标签连接线长度slice->setLabelPosition(QPieSlice::LabelOutside);  // 标签在外部
//       slice->setBorderWidth(2);  // 切片边框宽度}// 配置图例chart->legend()->setVisible(true);chart->legend()->setAlignment(Qt::AlignTrailing);chart->legend()->setFont(QFont("Arial", 9));// 连接悬停信号(突出显示效果)connect(series, &QPieSeries::hovered, [](QPieSlice *slice, bool state){if (state){slice->setExploded(true);      // 突出显示slice->setLabelVisible(true);  // 确保标签可见}else{slice->setExploded(false);slice->setPen(QPen(Qt::NoPen));}});}

3 逐段代码看效果

// 创建饼图对象
QPieSeries *series = new QPieSeries();
series->setHoleSize(0.35);  // 空心圆大小(0-1)
series->setPieSize(0.7);     // 饼图相对视图的大小// 创建Chart画布
QChart *chart = new QChart();
// 将饼图对象加入画布中
chart->addSeries(series);// 设置界面打开时有动画显示
chart->setAnimationOptions(QChart::AllAnimations); // 设置显示时的动画效果
chart->setTitle("饼图示例");
chart->setTitleFont(QFont("Arial", 14, QFont::Bold));
// 将画布设置到视图
chartView->setChart(chart);
chartView->setRenderHint(QPainter::Antialiasing);
chartView->chart()->setTheme(QChart::ChartTheme(0));
chartView->setRubberBand(QChartView::RectangleRubberBand);  // 矩形缩放

上述代码是标准操作流程

在这里插入图片描述

接下来才是操作饼图

// 添加数据切片
QPieSlice *slice1 = series->append("Search Engine", 1048);
QPieSlice *slice2 = series->append("Direct", 735);
QPieSlice *slice3 = series->append("Email", 580);
QPieSlice *slice4 = series->append("Union Ads", 484);
QPieSlice *slice5 = series->append("Video Ads", 300);
// 配置每个切片的样式
slice1->setColor(QColor(92, 123, 217));
slice2->setColor(QColor(159, 224, 128));
slice3->setColor(QColor(255, 220, 96));
slice4->setColor(QColor(255, 112, 112));
slice5->setColor(QColor(126, 211, 244));

在这里插入图片描述

series->setHoleSize(0);  // 空心圆大小(0-1)
series->setPieSize(0.7);     // 饼图相对视图的大小

在这里插入图片描述

series->setHoleSize(1);  // 空心圆大小(0-1)
series->setPieSize(0.7);     // 饼图相对视图的大小

在这里插入图片描述

这样,基础的饼图就绘制出来了,接下来是配置

// 设置标签格式:显示百分比和名称
for (auto slice : series->slices())
{qreal percent = (slice->value() / series->sum()) * 100.0;QString label = QString("%1\n%2%").arg(slice->label()).arg(percent, 0, 'f', 1);slice->setLabel(label);slice->setLabelVisible(true);slice->setLabelArmLengthFactor(0.05);  // 标签连接线长度slice->setLabelPosition(QPieSlice::LabelOutside);  // 标签在外部// slice->setBorderWidth(2);  // 切片边框宽度
}

在这里插入图片描述

slice->setLabelPosition(QPieSlice::LabelInsideNormal);

在这里插入图片描述

// 配置图例
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignTrailing);
chart->legend()->setFont(QFont("Arial", 9));

在这里插入图片描述

// 连接悬停信号(突出显示效果)
connect(series, &QPieSeries::hovered, [](QPieSlice *slice, bool state)
{if (state){slice->setExploded(true);      // 突出显示slice->setLabelVisible(true);  // 确保标签可见}else{slice->setExploded(false);slice->setPen(QPen(Qt::NoPen));}
});

在这里插入图片描述

4 让饼图动态显示

// 首先,肯定要有一个定时器吧
timer = new QTimer(this);connect(timer, &QTimer::timeout, this,[this]()
{// 预定义的类别名称数组static const QStringList categoryNames = {"Search Engine","Direct","Email","Union Ads","Video Ads"};// 获取饼图的切片QPieSeries *series = static_cast<QPieSeries *>(ui->graphicsView->chart()->series().at(0));QList<QPieSlice*> slices = series->slices();if (slices.size() >= 5){// 这里直接用索引,没有用series->appendslices[0]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[1]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[2]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[3]->setValue(QRandomGenerator::global()->bounded(10, 100));slices[4]->setValue(QRandomGenerator::global()->bounded(10, 100));}for (int i = 0; i < slices.size(); i++){qreal percent = (slices[i]->value() / series->sum()) * 100.0;
//            修改了这句代码,slice->label()会获取标签值,然后在标签值后不断追加数据
//            label = QString("%1\n%2%").arg(slice->label()).arg(percent, 0, 'f', 1);QString label = QString("%1\n%2%").arg(categoryNames[i]).arg(percent, 0, 'f', 1);slices[i]->setLabel(label);slices[i]->setLabelVisible(true);slices[i]->setLabelArmLengthFactor(0.05);slices[i]->setLabelPosition(QPieSlice::LabelOutside);}});
timer->start(1000);

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

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

相关文章

本地windows主机安装seafile部署详解,及无公网IP内网映射外网访问方案

在Windows上部署Seafile服务器是一个相对直接的过程&#xff0c;但需要你具备一定的系统管理知识。Seafile是一个开源的文件共享和协作平台&#xff0c;类似于Dropbox或Google Drive。 以下是在Windows上部署Seafile服务器的步骤&#xff1a; 1. 准备环境 确保你的Windows系…

Vue学习之---nextTick

前言&#xff1a;目前来说&#xff0c;nextTick我们遇到的比较少&#xff0c;至少对我来说是这样的&#xff0c;但是有一些聪明的小朋友早早就注意到这个知识点了。nextTick 是前端开发&#xff08;尤其是 Vue 生态&#xff09;中的核心知识点&#xff0c;原理上跟Vue的异步更新…

MS2691 全频段、多模导航、射频低噪声放大器芯片,应用于导航仪 双频测量仪

MS2691 全频段、多模导航、射频低噪声放大器芯片&#xff0c;应用于导航仪 双频测量仪 产品简述 MS2691 是一款具有 1164MHz  1615MHz 全频段、低功耗的低噪声放大器芯片。该芯片通过对外围电路的简单配置&#xff0c;使得频带具有宽带或窄带特性。支持不同频段的各种导…

学习STC51单片机30(芯片为STC89C52RCRC)

每日一言 当你感到疲惫时&#xff0c;正是成长的关键时刻&#xff0c;再坚持一下。 IIC协议 是的&#xff0c;IIC协议就是与我们之前的串口通信协议是同一个性质&#xff0c;就是为了满足模块的通信&#xff0c;其实之前的串口通信协议叫做UART协议&#xff0c;我们千万不要弄…

python打卡day47@浙大疏锦行

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 以下是不同卷积层特征图可视化的对比实现&#xff1a; import torch import matplotlib.pyplot as pltdef compare_conv_layers(model, input_tensor):# …

蓝桥杯单片机之通过实现同一个按键的短按与长按功能

实现按键的短按与长按的不同功能 问题分析 对于按键短按&#xff0c;通常是松开后实现其功能&#xff0c;而不会出现按下就进行后续的操作&#xff1b;而对于按键长按&#xff0c;则不太一样&#xff0c;按键长按可能分为两种情况&#xff0c;一是长按n秒后实现后续功能&…

数据导入技术(文档加载)

1. 简单文本的读取 用LangChain读入txt文档 # 读取单个txt文件 import os from langchain_community.document_loaders import TextLoader # 获取当前脚本文件所在的目录 script_dir os.path.dirname(__file__) print(f"获取当前脚本文件所在的目录&#xff1a;{script…

靶场(二十)---靶场体会小白心得 ---jacko

老样子开局先看端口&#xff0c;先看http端口 PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 |_http-title: H2 Database Engine (redirect) | http-methods: |_ Potentially risky methods: TRACE |_http-server-header:…

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…

|从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面

&#x1f411; |从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面 &#x1f411; 文章目录 &#x1f411; |从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面 &#x1f411;♈前言♈♈调取Deepseek大模型♈♒准备工作♒♒调用API♒ ♈将模型嵌入到ui界面中♈♈…

如何利用Elastic Stack(ELK)进行安全日志分析

在以下文章中&#xff0c;我将解释如何使用Elastic Stack&#xff08;ELK&#xff09;进行安全日志分析&#xff0c;以提高安全性和监控网络活动。ELK是一个功能强大的开源日志管理和分析平台&#xff0c;由Elasticsearch、Logstash和Kibana组成&#xff0c;适用于各种用例&…

网络安全-等级保护(等保)3-0 等级保护测评要求现行技术标准

################################################################################ 第三章&#xff1a;测评要求、测评机构要求&#xff0c;最终目的是通过测评&#xff0c;所以我们将等保要求和测评相关要求一一对应形成表格。 GB/T 28448-2019 《信息安全技术 网络安全等…

网络通讯知识——通讯分层介绍,gRPC,RabbitMQ分层

网络通讯分层 网络通讯分层是为了将复杂的网络通信问题分解为多个独立、可管理的层次&#xff0c;每个层次专注于特定功能。目前主流的分层模型包括OSI七层模型和TCP/IP四层&#xff08;或五层&#xff09;模型&#xff0c;以下是详细解析&#xff1a; 一、OSI七层模型&#…

gopool 源码分析

gopool gopool是字节跳动开源节流的gopkg包中协程池的一个实现。 关键结构 协程池&#xff1a; type pool struct {// The name of the poolname string// capacity of the pool, the maximum number of goroutines that are actually working// 协程池的最大容量cap int32…

【工作记录】接口功能测试总结

如何对1个接口进行接口测试 一、单接口功能测试 1、接口文档信息 理解接口文档的内容&#xff1a; 请求URL: https://[ip]:[port]/xxxserviceValidation 请求方法: POST 请求参数: serviceCode(必填), servicePsw(必填) 响应参数: status, token 2、编写测试用例 2.1 正…

Linux中su与sudo命令的区别:权限管理的关键差异解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…

乐观锁与悲观锁的实现和应用

乐观锁与悲观锁&#xff1a;原理、实现与应用详解 在并发编程和数据库操作中&#xff0c;乐观锁和悲观锁是两种重要的并发控制策略&#xff0c;它们在原理、实现方式和应用场景上存在显著差异。下面我们将通过图文结合的方式&#xff0c;深入探讨这两种锁机制。 一、基本概念 1…

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…

Redis主从复制原理二 之 主从复制工作流程

概述 本文紧接「Redis主从复制的原理一 之 概述」&#xff0c;详细介绍了Redis的主从服务过程及原理。 主从复制工作流程 主从复制过程大体可以分为3个阶段&#xff1a; 建立连接阶段&#xff08;即准备阶段&#xff09;数据同步阶段命令传播阶段 阶段一&#xff1a;建立连接阶…

Markdown基础(1.2w字)

1. Markdown基础 这次就没目录了&#xff0c;因为md格式太乱了写示例&#xff0c;展示那些都太乱了&#xff0c;导致目录很乱。 &#xff08;我是XX&#xff0c;出现了很多错误&#xff0c;有错误和我说&#xff09; 1.1 Markdown简介 Markdown是一种轻量级的标记语言&#…