【嵌入式——QT】Charts常见的图表的绘制
- 柱状图
- QBarSet
- QBarSeries
- QBarCategoryAxis
- 图示
- 饼图
- 堆叠柱状图
- 百分比柱状图
- 散点图和光滑曲线图
- 代码示例
柱状图
QBarSet
用于创建柱状图的数据集。
主要函数
- setLabel():设置数据集标签 ;
- setLabelBrush():设置标签的画刷 ;
- setLabelColor():设置标签的文字颜色 ;
- setLabelFont():设置标签的字体;
- setBorderColor():设置数据集的棒图边框颜色;
- setBrush():设置数据集的棒图画刷 ;
- setColor():设置数据集的棒图填充颜色 ;
- setPen():设置数据集的棒图边框画笔;
- append():添加一个数据到数据集 ;
- insert():在某个位置插入一个数据到数据集;
- remove():从某个位置开始删除一定数量的数据 ;
- replace():替换某个位置的数据 ;
- at():返回某个位置的数据;
- count():返回数据个数;
- sum():返回数据集内所有数据的和;
QBarSeries
柱状图序列,一个柱状图序列一般包含多个QBarSet数据集。
主要函数
- setBarWidth():设置数据棒的宽度;
- setLabelsVisible():设置数据棒的标签可见性;
- setLabelsFormat():设置数据棒的标签的格式;
- setLabelsPosition():设置数据棒的标签的位置;
- setLabelsAngle():设置数据棒的标签的角度;
- append():添加一个QBarSet数据集序列;
- insert():在某个位置插入一个QBarSet数据集到序列;
- remove():移除一个数据集,并删除数据集对象;
- take():移除出一个数据集,但是不删除数据集对象;
- clear():清除全部数据集,并删除数据集对象;
- barSets():返回数据集对象的列表;
- count():返回数据集个数;
QBarCategoryAxis
柱状图分类坐标,以文字标签形式表示的坐标。
主要函数
- append():添加一个类别到坐标轴;
- insert():在某个位置插入一个类别到坐标轴;
- replace():替换某个类别;
- remove():删除某个类别;
- clear():删除所有类别;
- at():返回某个索引位置的类别文字;
- count():返回类别的个数;
- setCategories():设置一个QStringList字符串列表作为坐标轴的类别文字,删除原来所有类别文字;
- setMin():设置坐标轴最小值;
- setMax():设置坐标轴最大值;
- setRange():设置坐标轴范围;
图示
饼图
堆叠柱状图
百分比柱状图
散点图和光滑曲线图
代码示例
QChartCommon.h
#ifndef QCHARTCOMMON_H
#define QCHARTCOMMON_H
#include <QMainWindow>
#include <QtCharts>
namespace Ui
{
class QChartCommon;
}
#define fixedColumnCount 5 //列数
#define initDataRowCount 6 //学生个数
#define colNoName 0 //姓名列编号
#define colNoMath 1 //数学列编号
#define colNoChinese 2 //语文列编号
#define colNoEnglish 3 //英语列编号
#define colNoAverage 4 //平均分列编号
class QChartCommon : public QMainWindow
{
Q_OBJECT
public:
explicit QChartCommon(QWidget* parent = nullptr);
~QChartCommon();
void initData();
void initTreeWidget();
void initBarChart();
void buildBarChart();
void initPieChart();
void buildPieChart();
void initStackedBar();
void buildStackedBar();
void initPercentBar();
void buildPercentBar();
void initScatterChart();
void buildScatterChart();
public slots:
void on_itemChanged(QStandardItem* item);
void on_pieSliceHighlight(bool flag);
private slots:
void on_tabWidget_currentChanged(int index);
void on_comboBox_2_currentIndexChanged(int index);
void on_pushButton_clicked();
void on_comboBox_currentIndexChanged(int index);
private:
Ui::QChartCommon* ui;
QStandardItemModel* theModel;
QChart* pieChart;
};
#endif // QCHARTCOMMON_H
QChartCommon.cpp
#include "QChartCommon.h"
#include "ui_QChartCommon.h"
#include <QTime>
QChartCommon::QChartCommon(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::QChartCommon)
{
ui->setupUi(this);
theModel = new QStandardItemModel(initDataRowCount, fixedColumnCount, this);
initData();
initTreeWidget();
connect(theModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(on_itemChanged(QStandardItem*)));
ui->tableView->setModel(theModel);
initBarChart();
initPieChart();
initStackedBar();
initPercentBar();
initScatterChart();
on_tabWidget_currentChanged(0);
}
QChartCommon::~QChartCommon()
{
delete ui;
}
void QChartCommon::initData()
{
QStringList headerList;
headerList<<u8"姓名"<<u8"数据"<<u8"语文"<<u8"英语"<<u8"平均分";
theModel->setHorizontalHeaderLabels(headerList);
qsrand(QTime::currentTime().second());
for(int i=0; i<theModel->rowCount(); i++) {
QString studName = QString::asprintf(u8"学生%2d", i+1);
QStandardItem* aItem = new QStandardItem(studName);
aItem->setTextAlignment(Qt::AlignHCenter);
theModel->setItem(i, colNoName, aItem);
qreal avgScore = 0;
for(int j=colNoMath; j<=colNoEnglish; j++) {
qreal score = 50.0+(qrand()%50);
avgScore+=score;
QStandardItem* aItem1 = new QStandardItem(QString::asprintf("%.0f", score));
aItem1->setTextAlignment(Qt::AlignHCenter);
theModel->setItem(i, j, aItem1);
}
QStandardItem* aItem2 = new QStandardItem(QString::asprintf("%.1f", avgScore/3));
aItem2->setTextAlignment(Qt::AlignHCenter);
theModel->setItem(i, colNoAverage, aItem2);
}
}
void QChartCommon::initTreeWidget()
{
QTreeWidgetItem* item1 = new QTreeWidgetItem(1001);
item1->setText(0, u8"60分以下");
item1->setText(1, u8"1");
item1->setText(2, u8"1");
item1->setText(3, u8"1");
item1->setText(4, u8"1");
item1->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
ui->treeWidget->addTopLevelItem(item1);
QTreeWidgetItem* item2 = new QTreeWidgetItem(1002);
item2->setText(0, u8"60-69分");
item2->setText(1, u8"2");
item2->setText(2, u8"2");
item2->setText(3, u8"2");
item2->setText(4, u8"2");
item2->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
ui->treeWidget->addTopLevelItem(item2);
QTreeWidgetItem* item3 = new QTreeWidgetItem(1003);
item3->setText(0, u8"70-79分");
item3->setText(1, u8"4");
item3->setText(2, u8"3");
item3->setText(3, u8"0");
item3->setText(4, u8"6");
item3->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
ui->treeWidget->addTopLevelItem(item3);
QTreeWidgetItem* item4 = new QTreeWidgetItem(1004);
item4->setText(0, u8"80-89分");
item4->setText(1, u8"1");
item4->setText(2, u8"1");
item4->setText(3, u8"2");
item4->setText(4, u8"0");
item4->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
ui->treeWidget->addTopLevelItem(item4);
QTreeWidgetItem* item5 = new QTreeWidgetItem(1005);
item5->setText(0, u8"90分以上");
item5->setText(1, u8"2");
item5->setText(2, u8"0");
item5->setText(3, u8"0");
item5->setText(4, u8"0");
item5->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
ui->treeWidget->addTopLevelItem(item5);
}
//柱状图
void QChartCommon::initBarChart()
{
QChart* chart = new QChart();
chart->setTitle(u8"Barchart演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsViewBar->setChart(chart);
ui->graphicsViewBar->setRenderHint(QPainter::Antialiasing);
}
//柱状图
void QChartCommon::buildBarChart()
{
QChart* chart = ui->graphicsViewBar->chart();//获取关联的chart
chart->removeAllSeries();//删除所有序列
chart->removeAxis(chart->axisX());//删除X轴
chart->removeAxis(chart->axisY());//删除Y轴
QBarSet* setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet* setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet* setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
QLineSeries* line = new QLineSeries();
line->setName(theModel->horizontalHeaderItem(colNoAverage)->text());
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(2);
line->setPen(pen);
for(int i=0; i<theModel->rowCount(); i++) {
setMath->append(theModel->item(i, colNoMath)->text().toInt());
setChinese->append(theModel->item(i, colNoChinese)->text().toInt());
setEnglish->append(theModel->item(i, colNoEnglish)->text().toInt());
line->append(QPointF(i, theModel->item(i, colNoMath)->text().toFloat()));
}
//柱状图序列
QBarSeries* series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series);
chart->addSeries(line);
//横坐标字符串
QStringList categories;
for(int i=0; i<theModel->rowCount(); i++) {
categories<<theModel->item(i, colNoName)->text();
}
//横坐标
QBarCategoryAxis* axisX = new QBarCategoryAxis();
// axisX->append(categories);
axisX->setCategories(categories);
chart->setAxisX(axisX, series);
chart->setAxisX(axisX, line);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
//纵坐标
QValueAxis* axisY = new QValueAxis();
axisY->setRange(0, 100);
axisY->setTitleText(u8"分数");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");
chart->setAxisY(axisY, series);
chart->setAxisY(axisY, line);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
}
//饼图
void QChartCommon::initPieChart()
{
pieChart = new QChart();
pieChart->setTitle(u8"Piechart演示");
pieChart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsViewPie->setChart(pieChart);
ui->graphicsViewPie->setRenderHint(QPainter::Antialiasing);
ui->comboBox->addItem(u8"数学", 0);
ui->comboBox->addItem(u8"语文", 1);
ui->comboBox->addItem(u8"英语", 2);
ui->comboBox->addItem(u8"平均分", 3);
ui->comboBox_2->addItem("ChartThemeLight", 0);
ui->comboBox_2->addItem("ChartThemeBlueCerulean", 1);
ui->comboBox_2->addItem("ChartThemeDark", 2);
ui->comboBox_2->addItem("ChartThemeBrownSand", 3);
ui->comboBox_2->addItem("ChartThemeBlueNcs", 4);
ui->comboBox_2->addItem("ChartThemeHighContrast", 5);
ui->comboBox_2->addItem("ChartThemeBlueIcy", 6);
ui->comboBox_2->addItem("ChartThemeQt", 7);
ui->doubleSpinBoxHole->setValue(0.20);
ui->doubleSpinBoxPie->setValue(0.70);
}
//饼图
void QChartCommon::buildPieChart()
{
QChart* chart = ui->graphicsViewPie->chart();
chart->removeAllSeries();
int colNo = 1+ui->comboBox->currentIndex();
QPieSeries* series = new QPieSeries();
//饼图中心空心的大小
series->setHoleSize(ui->doubleSpinBoxHole->value());
for(int i=0; i<=4; i++) {
//添加分块数据
QTreeWidgetItem* item = ui->treeWidget->topLevelItem(i);
series->append(item->text(0), item->text(colNo).toFloat());
// series->append(ui->comboBox->itemText(i), 25.0);
}
QPieSlice* slice;//饼图分块
for(int i=0; i<=4; i++) {
slice=series->slices().at(i);//获取分块
slice->setLabel(slice->label()+QString::asprintf(u8": %.0f 人,%.1f%%", slice->value(), slice->percentage()*100));
connect(slice, SIGNAL(hovered(bool)), this, SLOT(on_pieSliceHighlight(bool)));
}
//最后一个设置为exploded
slice->setExploded(true);
//必须添加完slice之后再设置
series->setLabelsVisible(true);
//添加饼图序列
chart->addSeries(series);
chart->setTitle("Piechart---"+ui->comboBox->currentText());
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
}
//堆叠图
void QChartCommon::initStackedBar()
{
QChart* chart = new QChart();
chart->setTitle(u8"StackedBar演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsViewStacked->setChart(chart);
ui->graphicsViewStacked->setRenderHint(QPainter::Antialiasing);
}
//堆叠图
void QChartCommon::buildStackedBar()
{
QChart* chart = ui->graphicsViewStacked->chart();
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
QBarSet* setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet* setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet* setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
for(int i=0; i<theModel->rowCount(); i++) {
//添加分数到数据集
setMath->append(theModel->item(i, colNoMath)->text().toInt());
setChinese->append(theModel->item(i, colNoChinese)->text().toInt());
setEnglish->append(theModel->item(i, colNoEnglish)->text().toInt());
}
//创建QStackedBarSeries对象并添加数据集
QStackedBarSeries* series = new QStackedBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);
chart->addSeries(series);
QStringList categories;
for(int i=0; i<theModel->rowCount(); i++) {
categories<<theModel->item(i, colNoName)->text();
}
//创建横轴
QBarCategoryAxis* axisX = new QBarCategoryAxis();
axisX->setCategories(categories);
chart->setAxisX(axisX);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
//创建Y轴
QValueAxis* axisY = new QValueAxis();
axisY->setRange(0, 300);
axisY->setTitleText(u8"总分");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");
chart->setAxisY(axisY);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignTop);
}
//百分比柱状图
void QChartCommon::initPercentBar()
{
QChart* chart = new QChart();
chart->setTitle(u8"PercentBar演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsViewPercent->setChart(chart);
ui->graphicsViewPercent->setRenderHint(QPainter::Antialiasing);
}
//百分比柱状图
void QChartCommon::buildPercentBar()
{
QChart* chart = ui->graphicsViewPercent->chart();
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
QBarSet* setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet* setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet* setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
QTreeWidgetItem* item;
QStringList categories;
for(int i=0; i<=4; i++) {
//添加分块数据
item = ui->treeWidget->topLevelItem(i);
categories<<item->text(0);
setMath->append(item->text(colNoMath).toFloat());
setChinese->append(item->text(colNoChinese).toFloat());
setEnglish->append(item->text(colNoEnglish).toFloat());
}
QPercentBarSeries* series = new QPercentBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);
chart->addSeries(series);
QBarCategoryAxis* axisX = new QBarCategoryAxis();
axisX->setCategories(categories);
chart->setAxisX(axisX);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
//创建Y轴
QValueAxis* axisY = new QValueAxis();
axisY->setRange(0, 100);
axisY->setTitleText(u8"百分比");
axisY->setTickCount(6);
axisY->setLabelFormat("%.1f");
chart->setAxisY(axisY, series);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
}
//散点图
void QChartCommon::initScatterChart()
{
QChart* chart = new QChart();
chart->setTitle(u8"ScatterChart演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsViewScatter->setChart(chart);
ui->graphicsViewScatter->setRenderHint(QPainter::Antialiasing);
}
//散点图
void QChartCommon::buildScatterChart()
{
QChart* chart = ui->graphicsViewScatter->chart();
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
QSplineSeries* seriesLine = new QSplineSeries();
seriesLine->setName("spline");
QPen pen;
pen.setColor(Qt::blue);
pen.setWidth(2);
seriesLine->setPen(pen);
QScatterSeries* series0 = new QScatterSeries();
series0->setName(u8"散点");
series0->setMarkerShape(QScatterSeries::MarkerShapeCircle);
series0->setBorderColor(Qt::black);
series0->setBrush(QBrush(Qt::red));
series0->setMarkerSize(12);
qsrand(QTime::currentTime().second());
for(int i=0; i<10; i++) {
int x = (qrand()%20);
int y= (qrand()%20);
series0->append(x, y); //散点序列
seriesLine->append(x, y); //光滑曲线
}
chart->addSeries(series0);
chart->addSeries(seriesLine);
chart->createDefaultAxes();//创建缺省坐标轴
chart->axisX()->setTitleText(u8"X轴");
chart->axisX()->setRange(-2, 22);
chart->axisY()->setTitleText(u8"Y轴");
chart->axisY()->setRange(-2, 22);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
}
void QChartCommon::on_itemChanged(QStandardItem* item)
{
if((item->column()<colNoMath) || (item->column()>colNoEnglish)) {
return;
}
int rowNo = item->row();
qreal avg = 0;
QStandardItem* aItem;
for(int i=colNoMath; i<=colNoEnglish; i++) {
aItem = theModel->item(rowNo, i);
avg += aItem->text().toDouble();
}
avg = avg/3;
aItem = theModel->item(rowNo, colNoAverage);
aItem->setText(QString::asprintf("%.1f", avg));
}
void QChartCommon::on_pieSliceHighlight(bool flag)
{
QPieSlice* slice = (QPieSlice*)sender();
slice->setExploded(flag);
}
void QChartCommon::on_tabWidget_currentChanged(int index)
{
switch(index) {
case 0:
buildBarChart();
break;
case 1:
buildPieChart();
break;
case 2:
buildStackedBar();
break;
case 3:
buildPercentBar();
break;
case 4:
buildScatterChart();
break;
}
}
void QChartCommon::on_comboBox_2_currentIndexChanged(int index)
{
switch(index) {
case 0:
pieChart->setTheme(QChart::ChartThemeLight);
break;
case 1:
pieChart->setTheme(QChart::ChartThemeBlueCerulean);
break;
case 2:
pieChart->setTheme(QChart::ChartThemeDark);
break;
case 3:
pieChart->setTheme(QChart::ChartThemeBrownSand);
break;
case 4:
pieChart->setTheme(QChart::ChartThemeBlueNcs);
break;
case 5:
pieChart->setTheme(QChart::ChartThemeHighContrast);
break;
case 6:
pieChart->setTheme(QChart::ChartThemeBlueIcy);
break;
case 7:
pieChart->setTheme(QChart::ChartThemeQt);
break;
}
}
void QChartCommon::on_pushButton_clicked()
{
buildPieChart();
}
void QChartCommon::on_comboBox_currentIndexChanged(int index)
{
buildPieChart();
}