Qt第二十天

目前完成柱状图绘制部分

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();
}

运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/theRookie1/article/details/85107635