Qt 画自定义饼图统计的例子

news2024/11/26 12:39:24

先给出结果图,这个例子是将各种事件分类然后统计的其比例,然后画饼图显示出来

这个是我仿照官方给的例子,让后自己理解后,修改的,要生成饼图,需要QT的 charts 支持,安装QT 没有选择这个的,需要下载这个模块,然后在.pro文件中年添加

QT += charts

首先重写饼图块,让鼠标悬浮在某个饼图块时,让这个块弹出来,然后显示块的信息,这个比较简单,如下所示

//头文件
#include <QtCharts/QPieSlice>

QT_CHARTS_USE_NAMESPACE

class CustomSlice : public QPieSlice
{
    Q_OBJECT

public:
    CustomSlice(QString label, qreal value);

public Q_SLOTS:
    void showHighlight(bool show);

};

//cpp文件

#include "customslice.h"

QT_CHARTS_USE_NAMESPACE

CustomSlice::CustomSlice(QString label, qreal value)
    : QPieSlice(label, value)
{
    connect(this, &CustomSlice::hovered, this, &CustomSlice::showHighlight);
}

void CustomSlice::showHighlight(bool show)
{
    setLabelVisible(show);//显示标签
    setExploded(show); // 弹出
}

主体代码如下,主要是初始化饼图,创建饼图,为饼图块随机上色,为饼图数据的显示做排序,只需要调用接口函数把相应的数据塞进去即可生成可视化的饼图

statisticwindow.h

#ifndef STATISTICCHARTSWINDOW_H
#define STATISTICCHARTSWINDOW_H

#include <QWidget>
#include <QVBoxLayout>
#include <QtCharts/QPieSeries>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QtCharts/QChartView>

class QPushButton;
class CustomSlice;
QT_CHARTS_USE_NAMESPACE

class StatisticChartsWindow : public QWidget
{
    Q_OBJECT
public:
    explicit StatisticChartsWindow(QWidget *parent = nullptr);
    ~StatisticChartsWindow();
    //创建一个饼图1
    void createPie1(QMap<QString, int> data, QString title);
    //创建一个饼图2
    void createPie2(QMap<QString, int> data, QString title);
    // 为饼图1添加块信息
    void appendSlice1(QString lable, int value);
    // 为饼图2添加块信息
    void appendSlice2(QString lable, int value);
    // 移除所有块信息
    void removeAllSlice();
    // 获取随机颜色为饼图的每个块上色
    Qt::GlobalColor getRandomColor();
    //获取排序后的数据
    QList<QMap<QString, int>> getsortListByValue(QMap<QString, int> &data);
    QVBoxLayout *VBoxLayout;

    QPieSeries *series1;
    QPieSeries *series2;
    QChart *chart1;
    QChart *chart2;
    QChartView *chartView1;
    QChartView *chartView2;
    QPushButton *closeButton;

    QList<CustomSlice*> CustomSlice1List;
    QList<CustomSlice*> CustomSlice2List;
    QList<Qt::GlobalColor> colorList;

signals:
    void closeSig();

public slots:
};

#endif // STATISTICCHARTSWINDOW_H

statisticwindow.cpp

#include "statisticwindow.h"
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QPieSeries>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QtCharts/QChartView>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QRandomGenerator>
#include "customslice.h"
#include <QPushButton>
#include "pushbutton.h"

StatisticChartsWindow::StatisticChartsWindow(QWidget *parent) : QWidget(parent)
{
    VBoxLayout = new QVBoxLayout(this);
    series1 = new QPieSeries(this);// 饼图一
    chart1 = new QChart();
    chart1->setAnimationOptions(QChart::AllAnimations);
    chart1->legend()->setVisible(true);
    chart1->legend()->setAlignment(Qt::AlignRight);//设置标签在右侧
    chartView1 = new QChartView(chart1);

    series2 = new QPieSeries(this);// 饼图一
    chart2 = new QChart();
    chart2->setAnimationOptions(QChart::AllAnimations);
    chart2->legend()->setVisible(true);
    chart2->legend()->setAlignment(Qt::AlignRight);//设置标签在右侧

    chartView2 = new QChartView(chart2);

    //底部添加关闭按钮
    closeButton = new QPushButton("关闭", this);
    QHBoxLayout *hlayout = new QHBoxLayout();
    hlayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
    hlayout->addWidget(closeButton);
    hlayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));

    //SC3C::Valwell::PushButton::initStyle(closeButton);
    QPalette palette = closeButton->palette();
    QColor color(19, 46, 74); // RGB红色
    palette.setColor(QPalette::Button, color);
    closeButton->setPalette(palette);
    closeButton->setStyleSheet("color: white;");

    colorList<<Qt::red<<Qt::white<<Qt::darkGray<<Qt::gray<<Qt::lightGray<<Qt::red<<Qt::green<<Qt::blue<<Qt::cyan
            <<Qt::magenta<<Qt::yellow<<Qt::darkRed<<Qt::darkGreen<<Qt::darkBlue<<Qt::darkCyan;


    chartView1->chart()->setTheme(QChart::ChartThemeBlueCerulean);
    chartView2->chart()->setTheme(QChart::ChartThemeBlueCerulean);
    VBoxLayout->addWidget(chartView1);
    VBoxLayout->addWidget(chartView2);
    VBoxLayout->addLayout(hlayout);
    VBoxLayout->layout()->setSpacing(1);//底部添加关闭

    connect(closeButton, &QPushButton::clicked, [=]() {
        this->hide();
        emit closeSig();
    });
    this->setWindowFlags(this->windowFlags() | Qt::WindowCloseButtonHint);
    this->setStyleSheet("background-color: rgb(19, 46, 74);");
}

StatisticChartsWindow::~StatisticChartsWindow()
{
    if(chart1) {
        delete  chart1;
    }
    if(chart2) {
        delete  chart2;
    }
}

void StatisticChartsWindow::createPie1(QMap<QString, int> data, QString title)
{
    // 创建一个饼图系列
    series1->clear();
    int count=0; //计算总数
    QMap<int, QList<QString>> map;

    for(auto it=data.begin(); it!=data.end(); it++) {
        count += it.value();
    }

    QList<QMap<QString, int>> sortList = getsortListByValue(data);// 根据条数比例排序,从大到小

    for(QMap<QString, int> map: sortList) {
        QString keyLable = map.firstKey();
        int num = map.value(keyLable);
        double ratio = num/1.0/count*100;

        QString ratioStr = QString::number(ratio, 'f', 1);
        QString lable = QString("%1,条数:%2,占比,%3%").arg(keyLable).arg(num).arg(ratioStr);
        appendSlice1(lable, num); // 添加到饼图中
    }
    // 创建一个新的图表并添加系列
    chart1->setTitle(title);
    //chart1->removeAllSeries();
    chart1->addSeries(series1);
}

void StatisticChartsWindow::createPie2(QMap<QString, int> data, QString title)
{
    // 创建一个饼图系列
    series2->clear();
    int count=0; //计算总数
    QMap<int, QList<QString>> map;

    for(auto it=data.begin(); it!=data.end(); it++) {
        count += it.value();
    }

    QList<QMap<QString, int>> sortList = getsortListByValue(data);

    for(QMap<QString, int> map: sortList) {
        QString keyLable = map.firstKey();
        int num = map.value(keyLable);
        double ratio = num/1.0/count*100;

        QString ratioStr = QString::number(ratio, 'f', 1);
        QString lable = QString("%1,条数:%2,占比,%3%").arg(keyLable).arg(num).arg(ratioStr);
        appendSlice2(lable, num);
    }
    // 创建一个新的图表并添加系列
    chart2->setTitle(title);
    //chart2->removeAllSeries();
    chart2->addSeries(series2);
}

void StatisticChartsWindow::appendSlice1(QString lable, int value)
{
    CustomSlice *customSlice = new  CustomSlice(lable, value);
    customSlice->setBrush(QBrush(getRandomColor())); //设置填充颜色
    //customSlice->setPen(QPen(Qt::black)); //设置线条颜色

    CustomSlice1List.append(customSlice);
    *series1 << customSlice;
}

void StatisticChartsWindow::appendSlice2(QString lable, int value)
{
    CustomSlice *customSlice = new  CustomSlice(lable, value);
    customSlice->setBrush(QBrush(getRandomColor())); //设置填充颜色
    CustomSlice2List.append(customSlice);
    *series2 << customSlice;}

void StatisticChartsWindow::removeAllSlice()
{
    for(CustomSlice* custom: CustomSlice1List) {
        series1->remove(custom);
    }
    for(CustomSlice* custom: CustomSlice2List) {
        series2->remove(custom);
    }
    qDeleteAll(CustomSlice1List);
    qDeleteAll(CustomSlice2List);
    CustomSlice1List.clear();
    CustomSlice2List.clear();
}

Qt::GlobalColor StatisticChartsWindow::getRandomColor()
{
    int randomValue = QRandomGenerator::global()->bounded(0, colorList.size()-1);
    return colorList.takeAt(randomValue);
}

QList<QMap<QString, int>> StatisticChartsWindow::getsortListByValue(QMap<QString, int> &data)
{
    QList<QMap<QString, int>> sortList;
    QList<int> valueList;
    for(auto it=data.begin(); it!=data.end(); it++) {
        if(!valueList.contains(it.value())) {
            valueList.append(it.value());
        }
    }
    //根据值逆序排序
    std::sort(valueList.begin(), valueList.end(), std::greater<int>());

    for(int value: valueList) {
        for(QString key: data.keys(value)) {
            QMap<QString, int> map;
            map.insert(key, value);
            sortList.append(map);
        }
    }
    return sortList;
}

我的这个例子是,点击统计按钮之后,获取相应的数据,然后生成相应的饼图

    QObject::connect(ui.statisticsBtn, &QPushButton::clicked, [=]() {
        g_dataCache->setSystemLog(SC3C::eSystemLogType::QUERY_SYSTEMLOG, QString("成功"),"查看日志统计");
        StatisticChartsWindow window;
        if(StatisticWindow) {
            tableView->hide();
            StatisticWindow->show();
            return;
        }
        StatisticWindow = new StatisticChartsWindow(q);
        QObject::connect(StatisticWindow, &StatisticChartsWindow::closeSig, q, [=]() {
            tableView->show();
        });
        //  标签名,  数量
        QMap<QString, int> map1 = { };
        QMap<QString, int> map2 = { };
        int logType = ui.logType->currentData().toInt();
        int eventType = ui.eventType->currentData().toInt();
        QString Name = ui.operatorName->currentText();
        tableModel.second->setFilterOperator("所有");
        // 获取数据,map1表示饼图一需要的数据
        getEventTypeStatisticHash(map1, map2);
        //恢复之前显示的
        tableModel.second->setFilterType(logType, eventType);
        tableModel.second->setFilterOperator(Name);
        //SC3C::Valwell::Widget::setBackgroundCommon2WithMargins(window);
        StatisticWindow->setFixedSize(q->size());
        //StatisticWindow->setStyleSheet("background-color: transparent;");
        StatisticWindow->createPie1(map1, "事件类型统计");
        StatisticWindow->createPie2(map2, "日志类型统计");
        StatisticWindow->show();
        tableView->hide();
    });

只需要把map放入创建饼图的函数即可,map中对应的是QMap<标签名,数量>,也就是饼图右侧的标签

        StatisticWindow->createPie1(map1, "事件类型统计");
        StatisticWindow->createPie2(map2, "日志类型统计");

这样就可以出饼图了

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

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

相关文章

RDMA Shared Receive Queue(四)

参考知乎文章《RDMA之Shared Receive Queue》&#xff1a;https://zhuanlan.zhihu.com/p/279904125 SRQ SRQ全称为Shared Receive Queue&#xff0c;即共享接受队列。在QP中&#xff0c;SQ用于下发SEND/WRITE/READ等操作&#xff0c;而RQ只用于下发RECV操作&#xff0c;对于本…

Bytebase x Hacktoberfest 2023 黑客啤酒节开源挑战邀请

&#x1f383;十月就要到了&#xff0c;年度开源庆典 Hacktoberfest 即将启动&#xff01;今年&#xff0c;Bytebase 再次加入 Hacktoberfest&#xff0c;欢迎大家一起参加&#x1f37a; Hacktoberfest 是什么 Hacktoberfest Hacker 黑客 Oktoberfest 啤酒节&#xff0c;每…

远程访问:让您随时与电脑保持连接

远程访问可以带来什么&#xff1f; ​如今&#xff0c;我们的大部分工作都是在电脑的帮助下完成的。但是&#xff0c;我们并不总是坐在工作电脑前&#xff0c;随身携带电脑也很不方便&#xff0c;尤其是当工作设备是台式电脑而不是笔记本电脑时。那么&#xff0c;当我们不在…

【EI会议征稿】2023年第二届信号处理、计算机网络与通信国际学术会议(SPCNC2023)

2023年第二届信号处理、计算机网络与通信国际学术会议&#xff08;SPCNC2023&#xff09; The 2nd International Conference on Signal Processing, Computer Networks and Communications 2023年第二届信号处理、计算机网络与通信国际学术会议&#xff08;SPCNC2023&#x…

纷享销客蝉联2023「Cloud100 China 」榜单,综合实力再获认可

近日&#xff0c;2023Cloud 100 China榜单正式发布&#xff0c;榜单由靖亚资本与崔牛会联合推出&#xff0c;纷享销客凭借着过硬的综合实力与卓越的技术创新能力&#xff0c;再次荣登榜单。 【Cloud 100 China】榜单旨在关注中国最具潜力的Cloud公司&#xff0c;上榜的 100 家企…

无需公网IP,实现公网SSH远程登录MacOS【内网穿透】

目录 前言 1. macOS打开远程登录 2. 局域网内测试ssh远程 3. 公网ssh远程连接macOS 3.1 macOS安装配置cpolar 3.2 获取ssh隧道公网地址 3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址 4.1 保留一个固定TCP端口地址 4.2 配置固定TCP端口地址 5. 使用固定TCP端…

AutoDL初体验

AutoDL初体验 真的很给力&#xff01; 相同的配置&#xff0c;在华为云上价格令人望而却步&#xff0c;AutoDL真的良心价&#xff01; 搞了个4090体验一下&#xff0c;一小时只要两块五&#xff08;主要是&#xff0c;之前没有GPU&#xff0c;好多想玩的LLM开源项目都体验不了&…

数字人直播系统开发哪家好?

随着互联网技术的不断发展&#xff0c;直播行业已经成为了一个炙手可热的领域。数字人直播系统作为直播行业的一种新型应用&#xff0c;通过虚拟形象与真人克隆的结合&#xff0c;为用户提供了一种全新的互动体验。那么&#xff0c;在众多开发公司中&#xff0c;哪家公司的数字…

jquery和jquery-ui拖动元素(vue2)

彩色小方块可以任意拖动&#xff0c;红色箭头指向的区域可以拖动 CDN在index.html文件中引入 <link rel"stylesheet" href"//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"><script src"https://code.jquery.com/jquery-3.6.0.min…

水利感知信息系统方案浅析

传统水利感知信息主要包括雨水工情信息&#xff0c;通常是利用信息监测技术、通信技术、网络技术、计算机技术&#xff0c;建立由雨量站、水位站、流量站等组成的雨水工情遥测系统&#xff0c;实现对流域、河流、湖泊、水库、水电站和灌区的固定或移动站点的降水量、水位、流量…

差值结构表达的吸引能

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A 中有5个点&#xff0c;B中有1个点&#xff0c;并且重合&#xff0c;统计迭代次数并排序。 其中有6组数据 差值结构 迭代次数 L1 L2 L1 E1 L2…

C函数学习总结

一.内存拷贝函数 void* memcpy(voidr* s1,const void* s2,size_t n); 该函数返回拷贝后的指针。比如说&#xff0c;它可以将一个字符数组缓冲区的内容拷贝到另一个缓冲区中, size_t n可以使用sizeof进行得到。 memmove(void *s1,const void* s2,size_t n); 如果目标区域和源区…

LeetCode 2251. 花期内花的数目:排序 + 二分

【LetMeFly】2251.花期内花的数目&#xff1a;排序 二分 力扣题目链接&#xff1a;https://leetcode.cn/problems/number-of-flowers-in-full-bloom/ 给你一个下标从 0 开始的二维整数数组 flowers &#xff0c;其中 flowers[i] [starti, endi] 表示第 i 朵花的 花期 从 st…

使用docker完成minio服务部署扩容备份迁移生产实践文档

一、minio服务扩容方案 当服务器存储空间不足的时候&#xff0c;需要进行扩容&#xff0c;扩容过程中需要短暂停机时间&#xff0c;预计在一小时内能够完成和恢复 统一注意事项 强烈建议为部署中的所有节点选择基本相似的硬件配置。确保硬件&#xff08;CPU、内存、主板、存…

【Spring Boot】操作Redis数据结构

🌿欢迎来到@衍生星球的CSDN博文🌿 🍁本文主要学习【Spring Boot】操作Redis数据结构 🍁 🌱我是衍生星球,一个从事集成开发的打工人🌱 ⭐️喜欢的朋友可以关注一下🫰🫰🫰,下次更新不迷路⭐️💠作为一名热衷于分享知识的程序员,我乐于在CSDN上与广大开发者…

OOTD耳机 | 国庆出游头戴式耳机推荐|轻装上阵出片神器

国庆假期马上就要来啦&#xff5e; 今天就来分享一款数码神器——头戴式耳机&#xff0c;穿搭拍照必备&#xff0c;特别适合假期出游哦&#xff01;轻装上阵出片神器——轻律Umelody U1头戴式蓝牙耳机&#xff01; 整个设计简约低调&#xff0c;棕色的为主调的包身&#xff0c;…

JMeter 设置请求头信息的详细步骤

在使用 JMeter 的过程中&#xff0c;我们会遇到需要设置请求头信息的场景。比如&#xff1a; POST 传过去的 Body 数据是 json 格式的。需要填添加头信息&#xff1a;Content-Type&#xff1a;application/json。 在 header 中用 token 来传用户的认证信息。 下面&#xff0c;…

服务器vs普通电脑

服务器&#xff0c;是一种高性能计算机&#xff0c;作为网络的节点&#xff0c;存储、处理网络上80&#xff05;的数据、信息&#xff0c;因此也被称为网络的灵魂。那么&#xff0c;服务器与普通电脑有什么不一样呢&#xff1f; 服务器VS普通电脑 普通电脑&#xff0c;通过终…

常用中间件-OAuth2

1. 微服务权限校验Session共享 1.1 微服务权限校验 实现2号方案。使用Redis作为Session统一存储。 首先配置一下Nacos&#xff0c;参考https://blog.csdn.net/weixin_43917045/article/details/132852850 然后为每个服务添加验证机制&#xff0c;先导入依赖 <!-- SpringS…

vs2019配置libcurl环境

一、libcurl下载地址&#xff1a;curl - Download 二、解压下载的压缩包&#xff0c;进入projects\Windows\VC14目录 三、用vs2019打开curl-all.sln工程&#xff0c;选择LIB Debug&#xff0c;x64进行编译 编译后的文件为&#xff1a;curl-8.2.1\build\Win64\VC14\LIB Debug\li…