QtCharts 饼图只弹出一个扇形切片

前言

QtCharts的基本用法可以参考:QtCharts 饼图的基本用法 (感谢~~)
如上述链接博主运行结果所示:

  1. 单击一个扇形切片可以使该扇形切片弹出,但是要收回需要再次单击该切片。
  2. 当依次单击每个扇形切片后,所有扇形都呈弹出状态,想要收回则需要依次再次单击每个切片。

对于第2点个人感觉有点麻烦,以下代码通过在原有槽函数的基础上获取了饼图的所有扇形切片列表,并默认设置每个切片弹出状态为false,然后再设置当前单击的切片的弹出状态。

//.h
QPieSeries			*m_PieSeries;

//.cpp
void ChartWidget::onPieSeriesClicked(QPieSlice* slice)
{
	// 只弹出一个扇形
	bool bExploded = slice->isExploded();
	QList<QPieSlice*> PieSliceList = m_PieSeries->slices();
	for (int i = 0; i < PieSliceList.size(); ++i)
	{
		PieSliceList.at(i)->setExploded(false);
	}

	slice->setExploded(!bExploded);
}

效果

  1. 同样的单击弹出一块扇形切片,再次单击该切片会收回;
  2. 单击弹出一块扇形切片A后,再单击另外一块切片B,则切片A将自动收回,切片B将弹出;

性能

对于响应性能肯定会有影响,随着切片数量的增加影响会随之扩大,但当前计算机的性能这点耗时可以忽略不记。
目前想到的方案仅是如此,不喜勿怪,大神请多指教~~

后续改进方案

通过连接每个QPieSlicevoid hovered(bool state); 信号,鼠标悬浮在每个扇形切片上方时,自动弹出,鼠标移出扇形切片区域后自动收回。

	//扇形
	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->setLabelFont(font);
		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);

		connect(pie_slice, SIGNAL(hovered(bool)), this, SLOT(onHoveredPieSlice(bool)));
	}
void MainWindow::onHoveredPieSlice(bool bState)
{
	QPieSlice* slice = static_cast<QPieSlice*>(sender());
	slice->setExploded(bState);
}

效果

在这里插入图片描述

完整代码

上传一下完整代码,防止链接失效。

// .h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_MainWindow.h"

#include <QtCharts>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = Q_NULLPTR);

	void InitChart();
	void InitChart2();

private slots:
	//点击
	void onPieSeriesClicked(QPieSlice*);
	void onHoveredPieSlice(bool bState);

private:
    Ui::MainWindow ui;
	//饼状图
	QPieSeries *pie_series;
	QPieSeries *pie_seriesGender;
};

#include "MainWindow.h"
#include <QString>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

	InitChart();
	InitChart2();
}

void MainWindow::InitChart()
{
	//饼状图
	pie_series = new QPieSeries(this);
	connect(pie_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(onPieSeriesClicked(QPieSlice*)));	

	//定义各扇形切片的颜色
	static const QStringList list_pie_color = {
		"#6480D6","#A1DC85","#FFAD25","#FF7777","#84D1EF","#4CB383",
	};

	//设置数据
	QList<qreal> list_data = { 10, 3.2, 20, 3.4, 35, 36 };

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

	//扇形
	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->setLabelFont(font);
		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);

		connect(pie_slice, SIGNAL(hovered(bool)), this, SLOT(onHoveredPieSlice(bool)));
	}

	//标题字体
	QFont font2 = qApp->font();
	font2.setBold(true);
	font2.setPointSize(22);

	//图表视图
	QChart* chart = new QChart;
	chart->setTitle(QStringLiteral("XXX统计饼图"));	
	chart->setTitleFont(font2);
	chart->setTheme(QChart::ChartThemeDark); //设置暗黑主题
	chart->setAnimationOptions(QChart::SeriesAnimations);	
	chart->addSeries(pie_series);//加入饼图

	//图例
	chart->legend()->setAlignment(Qt::AlignRight);
	chart->legend()->setBackgroundVisible(false);
	for (int i = 0; i < list_pie_color.size(); i++) {
		chart->legend()->markers(pie_series)[i]->setLabel(QStringLiteral("统计项") + QString::number(i + 1));
	}

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

	//加入布局
	QVBoxLayout* layout = new QVBoxLayout;
	layout->setContentsMargins(0, 0, 0, 0);
	layout->addWidget(chartView);
	ui.widget->setLayout(layout); 	// ui.widget --> ui拖拽的QWidget部件
}

void MainWindow::InitChart2()
{
	//饼状图
	pie_seriesGender = new QPieSeries(this);
	connect(pie_seriesGender, SIGNAL(clicked(QPieSlice*)), this, SLOT(onPieSeriesClicked(QPieSlice*)));

	//定义各扇形切片的颜色
	static const QStringList list_pie_color = { "#FF2200","#0066FF" };

	//设置数据
	QList<qreal> list_data = { 50, 60 };
	QStringList strGenderList;
	strGenderList << QStringLiteral("男") << QStringLiteral("女");

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

	//扇形
	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->setLabelFont(font);
		pie_slice->setBorderColor(list_pie_color[i]);
		pie_seriesGender->append(pie_slice);
		connect(pie_slice, SIGNAL(hovered(bool)), this, SLOT(onHoveredPieSlice(bool)));
	}

	QFont font2("微软雅黑");
	font2.setBold(true);
	font2.setPointSize(20);

	//图表视图
	QChart* chart = new QChart;
	chart->setTitle(QStringLiteral("男生女生参检统计饼图"));
	chart->setTitleFont(font2);
	chart->setTheme(QChart::ChartThemeDark); //设置暗黑主题
	chart->setAnimationOptions(QChart::SeriesAnimations);
	chart->addSeries(pie_seriesGender);//加入饼图

	//图例
	chart->legend()->setAlignment(Qt::AlignLeft);
	chart->legend()->setBackgroundVisible(false);
	for (int i = 0; i < list_pie_color.size(); i++) {
		chart->legend()->markers(pie_seriesGender)[i]->setLabel(strGenderList.at(i));
	}

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

	//加入布局
	QVBoxLayout* layout = new QVBoxLayout;
	layout->setContentsMargins(0, 0, 0, 0);
	layout->addWidget(chartView);
	ui.widget_2->setLayout(layout);	//  ui.widget --> ui拖拽的QWidget部件 
}

void MainWindow::onPieSeriesClicked(QPieSlice* slice)
{
	slice->setExploded(!slice->isExploded());
}

void MainWindow::onHoveredPieSlice(bool bState)
{
	QPieSlice* slice = static_cast<QPieSlice*>(sender());
	slice->setExploded(bState);
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值