Bootstrap

在QT中展示两个chart

使用QChart注意事项: 1、.pro文件中添加QT +=charts 2、.h文件添加

#include <QWidget>
#include <QtCharts/QChartGlobal>
#include <QtWidgets/QWidget>

QT_CHARTS_BEGIN_NAMESPACE class QChartView; class QChart;
QT_CHARTS_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE//此句必备 ```

在之前的文章中,我们实现了在QMainwindow中展示一个chart,下面我们就试着展示两个chart。如下图:
在这里插入图片描述
我在建立项目时,选择的基类是QWidget,不是QMainWindow。那么这两个有什么关系和区别呢?

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。

在这里插入图片描述
QWidget是能够在屏幕上显示的一切组件的父类。
如果是主窗口,就使用QMainWindow类;
如果不确定,有可能作为顶层窗口,也有可能嵌入到其他窗口,就使用QWidget类。
在创建窗口时还是有一定区别的,所以不能只是简单的一位QMainWindow是QWidget的派生类。

上代码:
需要注意的是,在.pro文件中,要加上QT +=charts

Widget.cpp

#include "widget.h"
#include "ui_widget.h"
//#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtWidgets/QGridLayout>
#include <QBarSet>
#include <QBarSeries>
#include <QBarCategoryAxis>

//此句必备
QT_CHARTS_USE_NAMESPACE

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QGridLayout *baseLayout = new QGridLayout();//布局管理器
/********************Creating Donutchart*****************/
    QPieSeries *series=new QPieSeries();
    series->setHoleSize(0.35);//圆孔大小
    series->append("Protein 4.2%",4.2);


    QPieSlice *slice=series->append("Fat 15.6%",15.6);//单个切片
    slice->setExploded();//使该切片突出
    slice->setLabelVisible();//显示切片的标签
    series->append("Other 23.8%", 23.8);
    series->append("Carbs 56.4%", 56.4);//若以圆心为原点,作xoy坐标系,则以y轴为起始轴,圆环的每一小部分按照编程顺序顺时针排列。
    QChartView *chartView=new QChartView();
    chartView->setRenderHint(QPainter::Antialiasing);//渲染抗锯齿
    chartView->chart()->setTitle("Donut with a lemon glaze (100g)");
    chartView->chart()->addSeries(series);
    chartView->chart()->legend()->setAlignment(Qt::AlignBottom);//图例放在底部
    chartView->chart()->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色
    chartView->chart()->legend()->setFont(QFont("Arial",7));//图例字体宋体7号字
    //将donutchart放置在widget中,并且这种方法可以使chart随窗口的拉动而动态变化
    baseLayout->addWidget(chartView,0,0);

    //*************Creating Bar Charts*********************//
    //本示例要展示五个人在每个月的某项数据,比如每个月掉多少头发
    //创建要展示的对象,本示例中是姓名,并设置不同对象在每个月的数据
    QBarSet *set0 = new QBarSet("Jane");
    QBarSet *set1 = new QBarSet("John");
    QBarSet *set2 = new QBarSet("Axel");
    QBarSet *set3 = new QBarSet("Mary");
    QBarSet *set4 = new QBarSet("Sama");
    *set0<<1<<2<<3<<4<<5<<6;
    *set1<<3<<7<<6<<5<<5<<2;
    *set2<<2<<8<<1<<3<<6<<5;
    *set3<<1<<3<<5<<7<<1<<6;
    *set4<<4<<3<<3<<6<<7<<2;
    //创建一个序列对象,并将上面的数据添加到序列中
    QBarSeries *bseries = new QBarSeries();
    bseries->append(set0);
    bseries->append(set1);
    bseries->append(set2);
    bseries->append(set3);
    bseries->append(set4);
    //创建一个QChart类的对象chart,并将series对象加入到chart中
    QChart *chart = new QChart();
    chart->addSeries(bseries);
    //设置标题和动画
    chart->setTitle("simple chart example");
    chart->setAnimationOptions(QChart::SeriesAnimations);//设置动画

    //创建坐标
    //首先创建一个字符串列表,作为横坐标
    QStringList *categories = new QStringList();
    *categories<<"Jane"<<"Feb"<<"Mar"<<"Apr"<<"May"<<"Jun";
    //创建一个类别轴对象
    QBarCategoryAxis *axis = new QBarCategoryAxis();
    axis->append(*categories);//添加横坐标,月份
    chart->createDefaultAxes();//设置默认坐标轴,虽然后面的设置会覆盖默认坐标轴,但是也要在后面设置之前进行初始设置
    chart->setAxisX(axis,bseries);//将类别轴对象(横坐标月)和序列对象(每个月的数据)作为参数,设置X轴。

    //设置图例
    chart->legend()->setVisible(true);//图例可见
    chart->legend()->setAlignment(Qt::AlignBottom);//将图例放在表底

    //将图标放到view中
    chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);//抗锯齿

    baseLayout->addWidget(chartView,0,1);
   
    setLayout(baseLayout);//Qwidget特有的
    //ui->centralWidget->setLayout(pHLayout);//QMainWindow专用
    //QMainWindow并没有setLayout()函数,因此不能使用setLayout()函数来设置layout,需要使用间接的方法。

}

Widget::~Widget()
{
    delete ui;
}


Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtCharts/QChartGlobal>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

QT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACE
typedef QPair<QPointF, QString> Data;
typedef QList<Data> DataList;
typedef QList<DataList> DataTable;

QT_CHARTS_USE_NAMESPACE//此句必备
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

};
#endif // WIDGET_H

但是,我们把DonutChart和BarChart的实现过程也放到了构造函数中,确实看上去太不简洁了,也不便于管理。所以我们可以将这两个的实现过程放在Widget类的私有函数中,需要时调用即可。

1、在widget.h中的私有部分,加上如下代码:
private:
QChart *creatDonutChart() const;
QChart *creatBarChart() const;
2、在功能函数中,新建一个QChart *chart,所有的操作都是基于chart进行处理的,最后return chart。
3、调用函数时
QChartView *chartView;
chartView=new QChartView(creatDonutChart());

上代码:
widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QtCharts/QChartView>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtWidgets/QGridLayout>
#include <QBarSet>
#include <QBarSeries>
#include <QBarCategoryAxis>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QGridLayout *baseLayout = new QGridLayout();//布局管理器
/********************Creating Donutchart*****************/

    QChartView *chartView;
    chartView=new QChartView(creatDonutChart());
    chartView->setRenderHint(QPainter::Antialiasing);//渲染抗锯齿
    //将donutchart放置在widget中,并且这种方法可以使chart随窗口的拉动而动态变化
    baseLayout->addWidget(chartView,0,0);

//*******************Creating Bar Chart*********************//

    chartView=new QChartView(creatBarChart());
    chartView->setRenderHint(QPainter::Antialiasing);//渲染抗锯齿
    //将donutchart放置在widget中,并且这种方法可以使chart随窗口的拉动而动态变化
    baseLayout->addWidget(chartView,0,1);
    setLayout(baseLayout);

}

Widget::~Widget()
{
    delete ui;
}

QChart *Widget::creatDonutChart() const
{
    QPieSeries *series=new QPieSeries();
    series->setHoleSize(0.35);//圆孔大小
    series->append("Protein 4.2%",4.2);


    QPieSlice *slice=series->append("Fat 15.6%",15.6);//单个切片
    slice->setExploded();//使该切片突出
    slice->setLabelVisible();//显示切片的标签
    series->append("Other 23.8%", 23.8);
    series->append("Carbs 56.4%", 56.4);//若以圆心为原点,作xoy坐标系,则以y轴为起始轴,圆环的每一小部分按照编程顺序顺时针排列。
    QChart *chart = new QChart;
    chart->setTitle("Donut with a lemon glaze (100g)");
    chart->addSeries(series);
    chart->legend()->setAlignment(Qt::AlignBottom);//图例放在底部
    chart->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色
    chart->legend()->setFont(QFont("Arial",7));//图例字体宋体7号字

    return chart;
}
QChart *Widget::creatBarChart() const
{
    //本示例要展示五个人在每个月的某项数据,比如每个月掉多少头发
    //创建要展示的对象,本示例中是姓名,并设置不同对象在每个月的数据
    QBarSet *set0 = new QBarSet("Jane");
    QBarSet *set1 = new QBarSet("John");
    QBarSet *set2 = new QBarSet("Axel");
    QBarSet *set3 = new QBarSet("Mary");
    QBarSet *set4 = new QBarSet("Sama");
    *set0<<1<<2<<3<<4<<5<<6;
    *set1<<3<<7<<6<<5<<5<<2;
    *set2<<2<<8<<1<<3<<6<<5;
    *set3<<1<<3<<5<<7<<1<<6;
    *set4<<4<<3<<3<<6<<7<<2;
    //创建一个序列对象,并将上面的数据添加到序列中
    QBarSeries *bseries = new QBarSeries();
    bseries->append(set0);
    bseries->append(set1);
    bseries->append(set2);
    bseries->append(set3);
    bseries->append(set4);
    //创建一个QChart类的对象chart,并将series对象加入到chart中
    QChart *chart = new QChart();
    chart->addSeries(bseries);
    //设置标题和动画
    chart->setTitle("simple chart example");
    chart->setAnimationOptions(QChart::SeriesAnimations);//设置动画

    //创建坐标
    //首先创建一个字符串列表,作为横坐标
    QStringList *categories = new QStringList();
    *categories<<"Jane"<<"Feb"<<"Mar"<<"Apr"<<"May"<<"Jun";
    //创建一个类别轴对象
    QBarCategoryAxis *axis = new QBarCategoryAxis();
    axis->append(*categories);//添加横坐标,月份
    chart->createDefaultAxes();//设置默认坐标轴,虽然后面的设置会覆盖默认坐标轴,但是也要在后面设置之前进行初始设置
    chart->setAxisX(axis,bseries);//将类别轴对象(横坐标月)和序列对象(每个月的数据)作为参数,设置X轴。

    //设置图例
    chart->legend()->setVisible(true);//图例可见
    chart->legend()->setAlignment(Qt::AlignBottom);//将图例放在表底
    return chart;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtCharts/QChartGlobal>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

QT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACE
typedef QPair<QPointF, QString> Data;
typedef QList<Data> DataList;
typedef QList<DataList> DataTable;

QT_CHARTS_USE_NAMESPACE//此句必备


class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
private:
    QChart *creatDonutChart() const;
    QChart *creatBarChart() const;

};
#endif // WIDGET_H

;