在QT中使用饼状图进行数据分析

1.使用QCharts绘制库

饼状图创建初始化:

cpp 复制代码
//饼状图初始化
void initChart()
{
    ChartDialogcom = new QDialog(this);
    ChartDialogcom->setWindowTitle("数据色阶统计图");
    ChartDialogcom->setStyleSheet("background-color: rgb(33, 73, 140);font-family: 'Microsoft YaHei';");
    ChartDialogcom->setFixedSize(500, 500);
    ChartDialogcom->setModal(false);
    // 移除问号按钮
    ChartDialogcom->setWindowFlags(ChartDialogcom->windowFlags() & ~Qt::WindowContextHelpButtonHint);
    //饼状图
    pie_series = new QPieSeries(this);
    // connect(pie_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(onPieSeriesClicked(QPieSlice*)));

    //定义各扇形切片的颜色
    // static QList<QColor> list_pie_color = {
    //     QColor(255, 255, 255),//白色
    //     QColor(0, 0, 180),   // 0.001 → 深蓝
    //     QColor(2, 6, 255),   // 0.2 → 纯蓝
    //     QColor(3, 255, 2),   // 0.4 → 绿色
    //     QColor(254, 255, 2), // 0.6 → 黄色
    //     QColor(254, 151, 4), // 0.8 → 橙色
    //     QColor(255, 70, 2)   // 1.0 → 红色
    // };
    // 预定义的17个热力图颜色(从蓝到红)
    static QList<QColor> list_pie_color = {
        // 蓝色系:7种渐变(从深蓝到淡蓝)
        QColor(255, 255, 255),//白色
        QColor(0, 0, 180),       // 1. 深蓝色
        QColor(0, 30, 210),      // 2. 暗蓝色
        QColor(0, 60, 235),      // 3. 中深蓝
        QColor(0, 90, 255),      // 4. 纯蓝色
        QColor(30, 130, 255),    // 5. 亮蓝色
        QColor(60, 170, 255),    // 6. 天蓝色
        QColor(90, 210, 255),    // 7. 淡天蓝色
        // 绿色系:4种渐变
        QColor(0, 220, 200),     // 8. 蓝绿色
        QColor(0, 230, 150),     // 9. 青绿色
        QColor(0, 240, 100),     // 10. 绿青色
        QColor(0, 255, 50),      // 11. 亮绿色
        // 黄色系:1种
        QColor(255, 255, 0),     // 12. 纯黄色
        // 橙色系:3种渐变
        QColor(255, 200, 0),     // 13. 橙黄色
        QColor(255, 150, 0),     // 14. 橙色
        QColor(255, 100, 0),     // 15. 深橙色
        // 红色系:1种
        QColor(255, 0, 0)        // 16. 纯红色
    };

    //设置数据
    QList<qreal> list_data = {0,0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0,0};

    //扇形
    for (int i = 0; i < list_pie_color.size(); i++) {
        QPieSlice* pie_slice = new QPieSlice(this);
        pie_slice->setLabelVisible(true);
        pie_slice->setValue(list_data[i]);
        pie_slice->setLabel(QString::number(list_data[i]));
        pie_slice->setColor(list_pie_color[i]);
        pie_slice->setLabelColor(list_pie_color[i]);
        pie_slice->setBorderColor(list_pie_color[i]);
        pie_series->append(pie_slice);
        slices.append(pie_slice);//加入饼状图显示

    }
    // 统一设置所有扇形的标签字体
    QFont sliceFont;
    sliceFont.setPointSize(12);
    sliceFont.setFamily("Microsoft YaHei"); // 可选:设置字体
    sliceFont.setBold(false);

    foreach(QPieSlice* slice, slices) {
        slice->setLabelFont(sliceFont);
    }
    //图表视图
    /*QChart**/ chart = new QChart;
    chart->setTitle("色阶统计可视图");
    //设置暗黑主题
    chart->setTheme(QChart::ChartThemeDark);

    //标题字体
    QFont font = qApp->font();
    font.setBold(true);
    font.setPointSize(16);
    chart->setTitleFont(font);

    //加入饼图
    chart->addSeries(pie_series);
    chart->setAnimationOptions(QChart::SeriesAnimations);

    //图例
    // //图例设置(关键:图例会显示QPieSlice的name属性,默认是label)
    // chart->legend()->setAlignment(Qt::AlignBottom);
    // chart->legend()->setBackgroundVisible(false);
    // QFont legendFont = chart->legend()->font();
    // legendFont.setPointSize(9);
    // legendFont.setFamily("Microsoft YaHei");
    // chart->legend()->setFont(legendFont);
    // 隐藏默认图例(关键步骤)
    chart->legend()->hide();
    chart->addSeries(pie_series);
    chart->setAnimationOptions(QtCharts::QChart::SeriesAnimations);

    //加入绘画视图
    /*QChartView* */chartView = new QChartView(this);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartView->setChart(chart);

    // 4. 自定义图例(核心:实现图例显示"序号:数据大小")
    // QWidget *legendWidget = new QWidget();
    // QHBoxLayout *legendLayout = new QHBoxLayout(legendWidget); // 横向布局,也可以用纵向QVBoxLayout
    // legendLayout->setAlignment(Qt::AlignCenter); // 居中对齐
    // legendLayout->setSpacing(20); // 每个图例项之间的间距
    // // 为每个切片创建图例项(颜色块 + 文本)
    // for (int i = 0; i < 17; i++) {
    //     // 容器:存放颜色块和文本
    //     QWidget *itemWidget = new QWidget();
    //     QHBoxLayout *itemLayout = new QHBoxLayout(itemWidget);
    //     itemLayout->setContentsMargins(0, 0, 0, 0);
    //     itemLayout->setSpacing(5); // 颜色块和文本的间距

    //     // 颜色块(显示切片的颜色)
    //     QLabel *colorLabel = new QLabel();
    //     colorLabel->setFixedSize(15, 15); // 颜色块大小
    //     colorLabel->setStyleSheet(QString("background-color: %1; border: 1px solid #ccc;")
    //                                   .arg(list_pie_color[i].name()));

    //     // 图例文本:显示"序号:数据大小"(你想要的内容)
    //     QLabel *textLabel = new QLabel();
    //     textLabel->setText(QString("%1").arg(list_data[i]));
    //     textLabel->setStyleSheet("color: white;"); // 适配暗黑主题,设置白色文本
    //     textLabel->setFont(QFont("Microsoft YaHei", 10)); // 字体和大小
    //     Charttextlabel.append(textLabel);
    //     // 添加到项布局
    //     itemLayout->addWidget(colorLabel);
    //     itemLayout->addWidget(textLabel);

    //     // 添加到图例布局
    //     legendLayout->addWidget(itemWidget);
    // }
    QWidget *legendWidget = new QWidget();
    legendWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    // 创建网格布局,2列,自动行数
    QGridLayout *legendLayout = new QGridLayout(legendWidget);
    legendLayout->setHorizontalSpacing(20); // 列间距
    legendLayout->setVerticalSpacing(5);    // 行间距

    for (int i = 0; i < 17; i++) {
        // 容器:存放颜色块和文本
        QWidget *itemWidget = new QWidget();
        QHBoxLayout *itemLayout = new QHBoxLayout(itemWidget);
        itemLayout->setContentsMargins(0, 0, 0, 0);
        itemLayout->setSpacing(5); // 颜色块和文本的间距

        // 颜色块(显示切片的颜色)
        QLabel *colorLabel = new QLabel();
        colorLabel->setFixedSize(15, 15); // 颜色块大小
        colorLabel->setStyleSheet(QString("background-color: %1; border: 1px solid #ccc;")
                                      .arg(list_pie_color[i].name()));

        // 图例文本:显示"序号:数据大小"
        QLabel *textLabel = new QLabel();
        textLabel->setText(QString("%1").arg(list_data[i]));
        textLabel->setStyleSheet("color: white;");
        textLabel->setFont(QFont("Microsoft YaHei", 10));
        Charttextlabel.append(textLabel);

        // 添加到项布局
        itemLayout->addWidget(colorLabel);
        itemLayout->addWidget(textLabel);

        // 计算行和列的位置
        int row = i / 9;     // 每2个换一行
        int column = i % 9;  // 0表示第一列,1表示第二列

        // 添加到网格布局
        legendLayout->addWidget(itemWidget, row, column);
    }
    // 5. 整体布局:图表在上,自定义图例在下
    QWidget *centralWidget = new QWidget();
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->setSpacing(10); // 图表和图例的间距
    mainLayout->addWidget(chartView);
    // mainLayout->addWidget(legendWidget, 0, Qt::AlignCenter); // 图例居中
    // 创建图例容器包装,确保更好的居中效果
    QWidget *legendContainer = new QWidget();
    QVBoxLayout *containerLayout = new QVBoxLayout(legendContainer);
    containerLayout->setContentsMargins(0, 0, 0, 0);
    containerLayout->addWidget(legendWidget, 0, Qt::AlignCenter);

    // 添加图例容器到主布局
    mainLayout->addWidget(legendContainer);
    // //加入布局
    // QVBoxLayout* layout = new QVBoxLayout;
    // layout->setContentsMargins(0, 0, 0, 0);
    // layout->addWidget(chartView);

    ChartDialogcom->setLayout(mainLayout);

    connect(pie_series, &QPieSeries::hovered, [](QPieSlice *slice, bool state) {
        static QPieSlice* lastHovered = nullptr;
        if (state && slice) {
            if (lastHovered) {
                lastHovered->setExploded(false);
            }
            slice->setExploded(true);
            lastHovered = slice;
        } else if (!state && lastHovered) {
            lastHovered->setExploded(false);
            lastHovered = nullptr;
        }
    });
}
cpp 复制代码
    //饼状图
    QPieSeries *pie_series;
    void initChart();
    QDialog *ChartDialogcom;
    QChart* chart;
    QChartView* chartView;
    QList<QPieSlice*> slices;
    QList<QLabel*> Charttextlabel;
    QTimer* ChartdataTimer;

使用定时器实时刷新数据更新饼状图:

cpp 复制代码
void onChartdataTimeout()
{
    QCPColorMap *colorMap = static_cast<QCPColorMap*>(ui->widget->plottable(0));
    if (!colorMap) return;
    // 获取热力图数据
    int nx = colorMap->data()->keySize();
    int ny = colorMap->data()->valueSize();
    // 收集所有数据点
    QVector<double> allData;
    allData.reserve(nx * ny);

    for (int x = 0; x < nx; ++x) {
        for (int y = 0; y < ny; ++y) {
            double value = colorMap->data()->cell(x, y);
            allData.append(value);
        }
    }
    int colorValue=maxcolorevalue/16;//获取颜色最小值到最大值的每份区间
    int NumberIntervals[17]={0};//存储数据区间个数
    int totalNumber=current_x_num*current_y_num;
    for(int i=0;i<totalNumber;i++)
    {
        if(allData.at(i)<1)
        {
            NumberIntervals[0]++;
        }else if(allData.at(i)<colorValue)
        {
            NumberIntervals[1]++;
        }else if(allData.at(i)<2*colorValue)
        {
            NumberIntervals[2]++;
        }else if(allData.at(i)<3*colorValue)
        {
            NumberIntervals[3]++;
        }else if(allData.at(i)<4*colorValue)
        {
            NumberIntervals[4]++;
        }else if(allData.at(i)<5*colorValue)
        {
            NumberIntervals[5]++;
        }else
        {
            NumberIntervals[6]++;
        }

    }

    //更新每个扇形的分布大小
    for (int i = 0; i < 17; i++) {
        slices.at(i)->setLabelVisible(true);
        slices.at(i)->setValue(NumberIntervals[i]);
        // slices.at(i)->setLabel(QString::number(NumberIntervals[i]/totalNumber*100)+"%");
        // 正确计算百分比:先转为浮点数,再计算
        double percentage = (static_cast<double>(NumberIntervals[i]) / totalNumber) * 100.0;

        // 设置标签:同时显示数量和百分比
        QString labelText = QString("%1%")
                                .arg(percentage, 0, 'f', 1);

        slices.at(i)->setLabel(labelText);

        Charttextlabel.at(i)->setText(QString::number(NumberIntervals[i]));
    }


}

实现效果图

相关推荐
亓才孓2 小时前
[认识异常和错误]java
java·开发语言
码农水水2 小时前
中国电网Java面试被问:流批一体架构的实现和状态管理
java·c语言·开发语言·面试·职场和发展·架构·kafka
反向跟单策略2 小时前
期货反向跟单-贵金属牛市中的反向跟单密码
大数据·人工智能·学习·数据分析·区块链
1***43802 小时前
C++跨平台开发的核心挑战线程管理等基础功能
开发语言·c++
做萤石二次开发的哈哈2 小时前
萤石开放平台 萤石可编程设备 | 设备脚本自定义开发
开发语言·python·萤石云·萤石·萤石开放平台
无风听海3 小时前
深入讲解 C# 中 string 如何支持 CultureInfo
开发语言·c#
yaoxin5211233 小时前
291. Java Stream API - 从正则表达式创建 Stream
java·开发语言
BHXDML3 小时前
Java 设计模式详解
java·开发语言·设计模式
CCPC不拿奖不改名3 小时前
数据处理与分析:pandas基础+面试习题
开发语言·数据结构·python·面试·职场和发展·pandas