前言
QtCharts的基本用法可以参考:QtCharts 饼图的基本用法 (感谢~~)
如上述链接博主运行结果所示:
- 单击一个扇形切片可以使该扇形切片弹出,但是要收回需要再次单击该切片。
- 当依次单击每个扇形切片后,所有扇形都呈弹出状态,想要收回则需要依次再次单击每个切片。
对于第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);
}
效果
- 同样的单击弹出一块扇形切片,再次单击该切片会收回;
- 单击弹出一块扇形切片A后,再单击另外一块切片B,则切片A将自动收回,切片B将弹出;
性能
对于响应性能肯定会有影响,随着切片数量的增加影响会随之扩大,但当前计算机的性能这点耗时可以忽略不记。
目前想到的方案仅是如此,不喜勿怪,大神请多指教~~
后续改进方案
通过连接每个QPieSlice的void 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);
}