1. 程式人生 > >Qt第二十天

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

執行結果
在這裡插入圖片描述