使用Qtcharts来进行曲线图的绘制,直接贴代码:
my_chart.h
#ifndef MY_CHART_H
#define MY_CHART_H
#include <QtCharts>
class MyChart
{
private:
// 坐标轴
QValueAxis axis_x;
QValueAxis axis_y;
qreal axis_x_min;
qreal axis_x_max;
qreal axis_y_min;
qreal axis_y_max;
QString x_format;
QString y_format;
// 图表
QChart *chart;
// 数据
QList<QList<QPointF>> data_list;
quint32 max_num;
// 曲线
QList<QLineSeries*> series_list;
quint32 series_num;
public:
MyChart(QChart *chart, quint32 max_points_num);
~MyChart();
void set_format_x (QString x_format, qreal x_min, qreal x_max);
void set_format_y (QString y_format, qreal y_min, qreal y_max);
void set_points_num(quint32 max_num);
quint32 add_series(QString name, QColor color);
void init();
void display_series_enable(quint32 index, bool enabled);
void refresh(quint32 index, qreal new_value);
};
#endif // MY_CHART_H
my_chart.cpp
传入参数
chart类指针和最大点数,曲线是由一个个点组成的
MyChart::MyChart(QChart *chart, quint32 points_num)
{
if(chart == NULL){
return;
}
this->chart = chart;
this->max_num = points_num;
if(max_num == 0){
qDebug() << "MyChart param error!" << endl;
max_num = 100;
}
this->series_num = 0;
}
初始化函数:
void MyChart::init()
{
// 初始化坐标轴
axis_x.setRange(axis_x_min, axis_x_max);
axis_x.setLabelFormat(x_format);
axis_x.setReverse(true); // x轴反转,右侧为时间0处
axis_y.setRange(axis_y_min, axis_y_max);
axis_y.setLabelFormat(y_format);
// 初始化图表
chart->setTheme(QChart::ChartThemeDark);
// 初始化数据与曲线 series_num是曲线数量,决定你画几条曲线,下面有函数可以去增加和删除曲线
for(quint32 j = 0; j < series_num; j++){
// 初始化数据
data_list[j].clear();
for(quint32 i = 0; i < max_num; i++){
qreal x_val = axis_x_max * (max_num - i) / max_num;
data_list[j].append(QPointF(x_val, 0));//往list里面填初始化的数据,用于显示初始曲线
}
// 初始化曲线
series_list[j]->clear();
for(quint32 i = 0; i < max_num; i++){
series_list[j]->append(QPointF(0,0));
}
series_list[j]->replace(this->data_list[j]);
/* 增加曲线 */
chart->addSeries(series_list[j]);
/* 设定x轴比例 也就是x轴格式,可以认为x轴一格是多大单位*/
chart->setAxisX(&axis_x, series_list[j]);
/* 设定Y轴比例*/
chart->setAxisY(&axis_y, series_list[j]);
}
}
设置X和Y的格式比例,这是在初始化之前就要设置好的
void MyChart::set_format_x (QString x_format, qreal x_min, qreal x_max)
{
this->x_format = x_format;
this->axis_x_min = x_min;
this->axis_x_max = x_max;
}
void MyChart::set_format_y (QString y_format, qreal y_min, qreal y_max)
{
this->y_format = y_format;
this->axis_y_min = y_min;
this->axis_y_max = y_max;
}
增加曲线
quint32 MyChart::add_series(QString name, QColor color)
{
QList<QPointF> *data = new QList<QPointF>();
this->data_list.append(*data);
QLineSeries *series = new QLineSeries();
series->setColor(color);
series->setName(name);
this->series_list.append(series);
this->series_num++;
return (this->series_num - 1);
}
曲线使能/失能
也就是可以控制哪条曲线显示,哪条曲线不显示,可以在UI上增加控件来控制,我是自己加了复选框控制的
void MyChart::display_series_enable(quint32 index, bool enabled)
{
if(enabled){
this->chart->addSeries(series_list[index]);
this->chart->setAxisX(&axis_x, series_list[index]);
this->chart->setAxisY(&axis_y, series_list[index]);
} else {
this->chart->removeSeries(series_list[index]);
}
}
曲线更新
此函数决定曲线实时显示
void MyChart::refresh(quint32 index, qreal new_value)
{
// 除第一个点外,每个点的x值都变为i-1处的x值
for(quint32 i = 1; i < max_num; i++){
qreal x_val = axis_x_max * (max_num - (i - 1)) / max_num;
data_list[index][i].setX(x_val);
}
//删去第一个点,新增数据在最后
data_list[index].removeFirst();
data_list[index].append(QPointF((axis_x_max * 1 / max_num), new_value));
series_list[index]->replace(data_list[index]);
}
mainwindow.cpp调用曲线:
// 初始化曲线绘图区
QChart* chart = NULL;
ui->ui_chart_spd->setRenderHint(QPainter::Antialiasing);
chart = ui->ui_chart_spd->chart();
this->chart_spd = new MyChart(chart, MAX_POINT);
chart_spd->set_format_x("%.1f", 0, 10);
chart_spd->set_format_y("%d", -1 * MAX_SPEED, MAX_SPEED);
series_index_spd_l = chart_spd->add_series("左电机速度", QColor(0xff, 0xff, 0x33)); // 亮黄
series_index_spd_r = chart_spd->add_series("右电机速度", QColor(0x33, 0xff, 0x33)); // 亮绿
series_index_target_l = chart_spd->add_series("左速度指令", QColor(0xff, 0x33, 0xff)); // 亮紫
series_index_target_r = chart_spd->add_series("右速度指令", QColor(0xff, 0x33, 0x33)); // 亮红
chart_spd->init();
// 把默认不显示的曲线关掉
if (!(ui->checkBox_spd_left->isChecked())) {
this->chart_spd->display_series_enable(series_index_spd_l, false);
}
if (!(ui->checkBox_spd_right->isChecked())) {
this->chart_spd->display_series_enable(series_index_spd_r, false);
}
if (!(ui->checkBox_target_left->isChecked())) {
this->chart_spd->display_series_enable(series_index_target_l, false);
}
if (!(ui->checkBox_target_right->isChecked())) {
this->chart_spd->display_series_enable(series_index_target_r, false);
}
mainwindow.h:
// 波形图相关
MyChart* chart_spd;
quint32 series_index_spd_l;
quint32 series_index_spd_r;
quint32 series_index_target_l;
quint32 series_index_target_r;
qint32 target_spd_l = 0;
qint32 target_spd_r = 0;
UI界面设置
增加一个window控件,将他按照上面图片进行提升
显示展示
上面的复选框可以控制是否显示相应曲线