目前完成柱状图绘制部分
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStandardItem>
#include <QStringList>
#include <QLineSeries>
#include <QBarSeries>
#include <QStandardItemModel>
#include <QItemSelectionModel>
#define fixedColumnCount 5 //数据模型的列数
#define iniDataRowCount 6 //学生个数
#define colNoName 0 //姓名的列编号
#define colNoMath 1 //数学的列编号
#define colNoChinese 2 //语文的列编号
#define colNoEnglish 3 //英语的列编号
#define colNoAverage 4 //平均分的列编号
#include <QtCharts> //必须这么设置
//using namespace QtCharts; //必须这么设置
QT_CHARTS_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QStandardItemModel *theModel;
void iniData();//初始化数据
void surveyData();//统计数据
void iniBarChart(); //柱状图初始化
void buildBarChart();//构建柱状图
void iniPiewChart(); //饼图初始化
void buildPieChart(); //构建饼图
void iniStackedBar(); //堆积图初始化
void buildStackedBar(); //构建堆积图
void iniPercentBar(); //初始化
void buildPercentBar(); //构建图表
void iniScatterChart(); //初始化
void buildScatterChart(); //构建图表
private slots:
//三个分数列数据变化时,重新计算平均分
void on_itemChanged(QStandardItem *item);
void on_btnBuildBarChart_clicked();
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
theModel=new QStandardItemModel(iniDataRowCount,fixedColumnCount,this);//使用行数,列数建立theModel
iniData();//初始化数据
surveyData();//数据统计
//数据模块的itemChanged信号与自定义槽函数关联
connect(theModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(on_itemChanged(QStandardItem*)));
ui->tableView->setModel(theModel);
iniBarChart();//柱状图初始化
//iniPiewChart();//饼状图初始化
//iniStackedBar();//堆叠图初始化
//iniPercentBar();//百分比图初始化
//iniScatterChart();//散点图初始化
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_itemChanged(QStandardItem *item)//自动计算平均分
{
if ((item->column()<colNoMath) || (item->column()>colNoEnglish))
return; //如果被修改的item不是数学、语文、英语,就退出
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); //获取平均分数据的item
aItem->setText(QString::asprintf("%.1f",avg)); //更新平均分数据
}
void MainWindow::iniData()
{
QStringList headerList;
headerList<<"姓名"<<"数学"<<"语文"<<"英语"<<"平均分";
theModel->setHorizontalHeaderLabels(headerList);//设置表头文字
qsrand(QTime::currentTime().second());//随机数种子
for(int i=0;i<theModel->rowCount();i++)
{
QString studName=QString::asprintf("学生%2d",i+1);
QStandardItem *aItem=new QStandardItem(studName);
aItem->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//水平垂直居中
theModel->setItem(i,colNoName,aItem);//设置姓名列
//设置分数列
qreal avgScore=0;
for(int j=colNoMath;j<=colNoEnglish;j++)
{
qreal score=50.0+qrand()%50;
avgScore+=score;
aItem=new QStandardItem(QString::asprintf("%.0f",score));
aItem->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
theModel->setItem(i,j,aItem);
}
//设置平均分列
aItem=new QStandardItem(QString::asprintf("%.0f",avgScore/3));
aItem->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//水平垂直居中
aItem->setFlags(aItem->flags()&!Qt::ItemIsEditable);//不可以编辑
theModel->setItem(i,colNoAverage,aItem);
}
}
void MainWindow::surveyData()//处理数据
{
int cnt50,cnt60,cnt70,cnt80,cnt90;//用于计算分段人数
qreal sumV,minV=0,maxV=0;
qreal val;
QTreeWidgetItem *item; //节点
int i,j;
for(i=colNoMath;i<=colNoAverage;i++)
{
sumV=0;
cnt50=0;
cnt60=0;
cnt70=0;
cnt80=0;
cnt90=0;
for(j=0;j<theModel->rowCount();j++)
{
val=theModel->item(j,i)->text().toDouble();
if (j==0)
{
minV=val;
maxV=val;
}
if (val<minV)
minV=val;
if (val>maxV)
maxV=val;
//////////////////////////
sumV+=val;
if (val<60)
cnt50++;
else if ((val>=60) && (val<70))
cnt60++;
else if ((val>=70) && (val<80))
cnt70++;
else if ((val>=80) && (val<90))
cnt80++;
else
cnt90++;
}
item=ui->treeWidget->topLevelItem(0); //<60
item->setText(i,QString::number(cnt50));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(1); //60
item->setText(i,QString::number(cnt60));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(2); //70
item->setText(i,QString::number(cnt70));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(3); //80
item->setText(i,QString::number(cnt80));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(4); //90
item->setText(i,QString::number(cnt90));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(5); //average
item->setText(i,QString::number(sumV/theModel->rowCount()));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(6); //max
item->setText(i,QString::number(maxV));
item->setTextAlignment(i,Qt::AlignHCenter);
item=ui->treeWidget->topLevelItem(7); //min
item->setText(i,QString::number(minV));
item->setTextAlignment(i,Qt::AlignHCenter);
}
}
void MainWindow::iniBarChart()//柱状图初始化
{
QChart *chart = new QChart(); //创建chart
chart->setTitle("Barchart演示");
chart->setAnimationOptions(QChart::AllAnimations);//动画效果
ui->chartViewBar->setChart(chart); //为ChartView设置chart
ui->chartViewBar->setRenderHint(QPainter::Antialiasing);//反锯齿
}
void MainWindow::buildBarChart()//构造柱状图
{
QChart *chart=ui->chartViewBar->chart();//获取chartView关联的chart
//清空序列,坐标轴
chart->removeAllSeries();//删除所有序列
chart->removeAxis(chart->axisX());//删除坐标轴
chart->removeAxis(chart->axisY());
//QBarSet类表示条形图中的一组
//创建三个barset数据集,从数据模型的表头获取数据
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());//设置名称
//创建Pen
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,colNoAverage)->text().toFloat()));
}
//创建QBarSeries,并添加三个数据集
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);//添加横坐标文字列表
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("分数");
axisY->setTickCount(6);//分隔个数
axisY->setLabelFormat("%.0f");//标签格式
chart->setAxisY(axisY,series);
chart->setAxisY(axisY,Line);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
}
void MainWindow::on_btnBuildBarChart_clicked()
{
buildBarChart();
}
运行结果