Qt QChartView 实现如图
Answer
To achieve the desired pie chart display in Qt with percentages shown on each slice, you need to create a QPieSeries
, add slices to it, calculate and display the percentage for each slice, and add the series to a QChart
. Then, display the chart using a QChartView
.
Here’s a detailed example to implement this:
QPieSeries
.QChartView
to display the chart.Define the class to manage the chart and the pie series.
#ifndef CUSTOMCHARTVIEW_H
#define CUSTOMCHARTVIEW_H
#include
#include
#include
QT_CHARTS_USE_NAMESPACE
class CustomChartView : public QChartView {
Q_OBJECT
public:
explicit CustomChartView(QWidget* parent = nullptr);
void updatePieSeriesWithPercentages();
private:
QChart* chart;
QPieSeries* pieSeries;
};
#endif // CUSTOMCHARTVIEW_H
Implement the logic for creating the pie chart and updating the slice labels with percentages.
#include "CustomChartView.h"
#include
#include
CustomChartView::CustomChartView(QWidget* parent)
: QChartView(new QChart(), parent), chart(chart()) {
setRenderHint(QPainter::Antialiasing);
// Set up the pie series
pieSeries = new QPieSeries();
pieSeries->append("Advanced Digital Camera", 13);
pieSeries->append("Full Frame Digital Camera", 12);
pieSeries->append("Independent Filmmaker Camcorder", 22);
pieSeries->append("Lens Adapter", 2);
pieSeries->append("Macro Zoom Lens", 2);
pieSeries->append("Slim Digital Camera", 8);
pieSeries->append("SLR Digital Camera", 39);
pieSeries->append("USB Cable", 3);
// Add the series to the chart
chart->addSeries(pieSeries);
chart->setTitle("Chart Title");
// Customize the legend
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
// Update the pie series to show percentages
updatePieSeriesWithPercentages();
}
void CustomChartView::updatePieSeriesWithPercentages() {
// Calculate the total value of all slices
qreal totalValue = 0;
for (const QPieSlice* slice : pieSeries->slices()) {
totalValue += slice->value();
}
// Update each slice's label to show the percentage
for (QPieSlice* slice : pieSeries->slices()) {
qreal percentage = (slice->value() / totalValue) * 100;
slice->setLabel(QString("%1 %2%").arg(slice->label()).arg(percentage, 0, 'f', 0));
}
}
Set up the main application to display the chart.
#include
#include
#include "CustomChartView.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QMainWindow window;
CustomChartView* chartView = new CustomChartView(&window);
window.setCentralWidget(chartView);
window.resize(800, 600);
window.show();
return a.exec();
}
CustomChartView Class:
CustomChartView
class inherits from QChartView
and manages the pie chart and pie series.updatePieSeriesWithPercentages Method:
slice->setLabel
is used to update the label, formatted with the original label and the calculated percentage.Main Application:
CustomChartView
and sets it as the central widget of the main window.This setup will create a pie chart with each slice labeled with both its name and its percentage of the total. The labels will be formatted to show no decimal places for the percentage. You can adjust the formatting as needed for your specific requirements.
You can further customize the appearance and behavior of the chart and slices, such as:
void CustomChartView::updatePieSeriesWithPercentages() {
// Calculate the total value of all slices
qreal totalValue = 0;
for (const QPieSlice* slice : pieSeries->slices()) {
totalValue += slice->value();
}
// Update each slice's label to show the percentage
for (QPieSlice* slice : pieSeries->slices()) {
qreal percentage = (slice->value() / totalValue) * 100;
slice->setLabel(QString("%1 %2%").arg(slice->label()).arg(percentage, 0, 'f', 0));
// Customize each slice
slice->setLabelVisible(true);
slice->setPen(QPen(Qt::black, 1));
slice->setBrush(QBrush(Qt::lightGray));
// Example of exploding a particular slice
if (slice->label().contains("SLR Digital Camera")) {
slice->setExploded(true);
slice->setBrush(QBrush(Qt::red));
}
}
}
This example adds further customization to each slice, making the chart more interactive and visually appealing.
want t ---> slice->setLabel only show percentage
If you want each slice's label to only show the percentage without the category name, you can update the updatePieSeriesWithPercentages
method to set the label accordingly. Here's how you can modify the existing implementation to achieve this:
No changes needed here.
Update the updatePieSeriesWithPercentages
method to set the label to only display the percentage.
cpp
#include "CustomChartView.h"
#include
#include
CustomChartView::CustomChartView(QWidget* parent)
: QChartView(new QChart(), parent), chart(chart()) {
setRenderHint(QPainter::Antialiasing);
// Set up the pie series
pieSeries = new QPieSeries();
pieSeries->append("Advanced Digital Camera", 13);
pieSeries->append("Full Frame Digital Camera", 12);
pieSeries->append("Independent Filmmaker Camcorder", 22);
pieSeries->append("Lens Adapter", 2);
pieSeries->append("Macro Zoom Lens", 2);
pieSeries->append("Slim Digital Camera", 8);
pieSeries->append("SLR Digital Camera", 39);
pieSeries->append("USB Cable", 3);
// Add the series to the chart
chart->addSeries(pieSeries);
chart->setTitle("Chart Title");
// Customize the legend
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
// Update the pie series to show percentages
updatePieSeriesWithPercentages();
}
void CustomChartView::updatePieSeriesWithPercentages() {
// Calculate the total value of all slices
qreal totalValue = 0;
for (const QPieSlice* slice : pieSeries->slices()) {
totalValue += slice->value();
}
// Update each slice's label to show only the percentage
for (QPieSlice* slice : pieSeries->slices()) {
qreal percentage = (slice->value() / totalValue) * 100;
slice->setLabel(QString("%1%").arg(percentage, 0, 'f', 0));
// Optional: Customize each slice
slice->setLabelVisible(true);
slice->setPen(QPen(Qt::black, 1));
slice->setBrush(slice->color()); // Keep the default color
}
}
cpp
No changes needed here.
CustomChartView Class:
CustomChartView
class inherits from QChartView
and manages the pie chart and pie series.updatePieSeriesWithPercentages Method:
slice->setLabel
is used to update the label, formatted to show the percentage with no decimal places.Main Application:
CustomChartView
and sets it as the central widget of the main window.This setup will create a pie chart with each slice labeled only with its percentage of the total. The labels will be formatted to show no decimal places for the percentage. You can adjust the formatting as needed for your specific requirements.
Want to -->1, only show the percentage on the pie slice. And 2, on AlignRight, only show the whole name
I apologize for the mistake. Let's correct it properly. The issue arises because we overwrite the slice's label with the percentage, and we need to preserve the original label (the name) for the legend.
Here's a revised approach:
No changes needed here.
Update the updatePieSeriesWithPercentages
method and ensure the legend labels are set correctly.
#include "CustomChartView.h"
#include
#include
CustomChartView::CustomChartView(QWidget* parent)
: QChartView(new QChart(), parent), chart(chart()) {
setRenderHint(QPainter::Antialiasing);
// Set up the pie series
pieSeries = new QPieSeries();
pieSeries->append("Advanced Digital Camera", 13);
pieSeries->append("Full Frame Digital Camera", 12);
pieSeries->append("Independent Filmmaker Camcorder", 22);
pieSeries->append("Lens Adapter", 2);
pieSeries->append("Macro Zoom Lens", 2);
pieSeries->append("Slim Digital Camera", 8);
pieSeries->append("SLR Digital Camera", 39);
pieSeries->append("USB Cable", 3);
// Add the series to the chart
chart->addSeries(pieSeries);
chart->setTitle("Chart Title");
// Customize the legend
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
// Update the pie series to show percentages
updatePieSeriesWithPercentages();
}
void CustomChartView::updatePieSeriesWithPercentages() {
// Calculate the total value of all slices
qreal totalValue = 0;
for (const QPieSlice* slice : pieSeries->slices()) {
totalValue += slice->value();
}
// Update each slice's label to show only the percentage
int index = 0;
for (QPieSlice* slice : pieSeries->slices()) {
qreal percentage = (slice->value() / totalValue) * 100;
QString originalLabel = slice->label();
slice->setLabel(QString("%1%").arg(percentage, 0, 'f', 0));
chart->legend()->markers(pieSeries).at(index++)->setLabel(originalLabel);
// Optional: Customize each slice
slice->setLabelVisible(true);
slice->setPen(QPen(Qt::black, 1));
slice->setBrush(slice->color()); // Keep the default color
}
}
CustomChartView Class:
CustomChartView
class inherits from QChartView
and manages the pie chart and pie series.updatePieSeriesWithPercentages Method:
Main Application:
CustomChartView
and sets it as the central widget of the main window.This corrected setup ensures that each pie slice is labeled with its percentage of the total, and the legend on the right displays the full names of the slices. This approach keeps the chart clear and informative.
Reference:
c++ - 在 Qt 饼图中显示百分比? - IT工具网 (coder.work)