Qt实现图表绘制

来来来,今天新学习到了一个好东西,就是图表的绘制,这玩意在一般的项目开发中的使用频率还是非常高滴,毕竟相对于数字来说,这个东西更能体现出数据的变化,主要是耐看啊!!!废话不多,我们直接上教程。

Qt实现图表绘制

1.绘制ui界面

创建项目我们就不多说了,说的太多了麻烦。

我是这样设计的,因为只是为了实践,所以没有考虑吧好看的因素。

一共是三个控件:1.lable2.button 3.Graphics View,老规矩,先将1,2水平布局,然后选中Widget对象后点击垂直布局

1.lable: 就是一个标签,用于显示我们的这个图表是干什么的,

2.button:转到槽,来控制保存图像

3.Graphics view:来显示我们的图表

2.编写代码

1.编写头文件

首先是头文件,毕竟我们要实现图表和绘制曲线和定时器随机数的生成。

1.这是.cpp的
#include "QChartView" // 包含QChartView类,用于显示图表
#include "QChart" // 包含QChart类,用于创建图表
#include "QValueAxis" // 包含QValueAxis类,用于创建值轴
#include "QSplineSeries" // 包含QSplineSeries类,用于创建曲线系列
#include "QTimer" // 包含QTimer头文件,用于定时器
#include <QRandomGenerator> // 用于生成随机数
#include "QMessageBox" // 包含QMessageBox类,用于显示消息框
2. 这是.h的
#include <QWidget>
#include <QChartView>
#include <QChart>
#include <QSplineSeries>
#include <QValueAxis>
#include <QTimer>

2.编写定时器

先在widget.h中定义我们的time

qreal time;               // 保存时间轴上的时间

然后在widget.cpp中初始化并连接我们的槽,(这里的槽是用来更新我们图像显示的,我们直接在定时器的初始化这里连接了)

// 初始化定时器并连接到 updateChart 槽
    QTimer *timer = new QTimer(this); // 创建定时器
    connect(timer, &QTimer::timeout, this, &Widget::updateChart); // 连接定时器超时信号到槽函数
    timer->start(1000); // 启动定时器,每隔1000毫秒(1秒)触发一次

3.编写图表和曲线的实现

1.初始化类成员变量

我们图表中有两个成员,一个是图表,一个是图表中的曲线

widget.h文件中声名一下:

QChart *chart;            // 保存图表对象
    QSplineSeries *splineSeries; // 保存曲线对象

widget.cpp中定义:

// 初始化类成员变量 chart 和 splineSeries
    chart = new QChart(); // 创建图表对象
    splineSeries = new QSplineSeries(); // 创建曲线系列对象

我们这里直接把初始点也定义出来吧

// 为 splineSeries 添加初始点
    splineSeries->append(0, 0); // 在曲线系列中添加点(0,0)

2.设置画笔

之前的文章中有写,其实这些线呢,是由QPen这个画笔函数搭配相应的函数来实现绘图的

QPen pen(QColor(0xff5566)); // 创建一个红色画笔
    splineSeries->setPen(pen); // 设置曲线系列的画笔

3.添加配置坐标轴并将曲线添加到图表中

我们创建好了图表,图表中要有XY轴,坐标轴要有相应的参数等,来看个图吧:(括号括起来的部分)

chart->addSeries(splineSeries); // 将曲线系列添加到图表中

    // 创建坐标轴
    QValueAxis *valueAxisX = new QValueAxis; // 创建X轴
    QValueAxis *valueAxisY = new QValueAxis; // 创建Y轴

    // 设置坐标轴范围
    valueAxisX->setRange(0, 5000); // 设置X轴范围为0到5000
    valueAxisY->setRange(0, 100); // 设置Y轴范围为0到100
    valueAxisX->setTitleText("时间/ms"); // 设置X轴标题
    valueAxisY->setTitleText("温度/°C"); // 设置Y轴标题

    valueAxisX->setLabelFormat("%d"); // 设置X轴标签格式为整数
    valueAxisY->setLabelFormat("%d"); // 设置Y轴标签格式为整数

    // 将坐标轴添加到图表并附加到曲线
    chart->addAxis(valueAxisX, Qt::AlignBottom); // 将X轴添加到图表底部
    chart->addAxis(valueAxisY, Qt::AlignLeft); // 将Y轴添加到图表左侧
    splineSeries->attachAxis(valueAxisX); // 将曲线系列附加到X轴
    splineSeries->attachAxis(valueAxisY); // 将曲线系列附加到Y轴

4.设置标题和图例显示

就是显示圈起来的那个玩意:

// 设置图表标题和图例
    chart->setTitle("温度与时间"); // 设置图表标题
    chart->legend()->setVisible(true); // 显示图例

5.显示图表

我们都弄好了之后我们要将我们设置好的图表显示到我们的UI文件当中。

// 将图表设置到图表视图中
    ui->chartview->setChart(chart); // 将图表对象设置到ui中的chartview控件

3.槽函数的编写

我们使用了两个槽函数,一个是图表中点的生成的槽函数,一个是保存按钮的槽函数,我们实现以下

1.图表中点的生成的槽函数

widget.h文件中声名一下这个函数

public slots:
    void updateChart();

widget.cpp中定义实现一下:

// 更新图表的槽函数
void Widget::updateChart()
{
    qreal randomTemp = QRandomGenerator::global()->bounded(0,100); // 生成0到100之间的随机数作为温度

    time += 1000; // 时间增加1000毫秒

    splineSeries->append(time,randomTemp); // 在曲线系列中添加新点

    QValueAxis *axisX = static_cast<QValueAxis*>(chart->axes(Qt::Horizontal).first()); // 获取X轴
    axisX->setRange(time - 5000, time); // 设置X轴范围,确保显示最近5秒的数据
}

2.保存按钮的槽函数:

这个直接在UI文件中转到槽就可以,他就会在widget.h文件中给你创建好

 

// 按钮点击槽函数
void Widget::on_pushButton_clicked()
{
    // 确保 X 轴显示所有数据
    if (!splineSeries->points().isEmpty()) {
        // 获取曲线中的最小和最大时间值
        qreal minX = splineSeries->points().first().x();
        qreal maxX = splineSeries->points().last().x();

        // 设置X轴范围覆盖所有数据点
        QValueAxis *axisX = static_cast<QValueAxis*>(chart->axes(Qt::Horizontal).first());
        axisX->setRange(minX, maxX);
    }

    // 获取 QChartView 的图像
    QPixmap pixmap = ui->chartview->grab(); // 捕获chartview的图像

    // 保存图像为 PNG 文件到当前项目目录
    QString fileName = "full_chart.png"; // 自定义保存文件名
    if (pixmap.save(fileName)) {
        // 成功保存后显示提示信息
        QMessageBox::information(this, "保存成功", "图表已保存为: " + fileName);
    } else {
        // 如果保存失败,提示错误信息
        QMessageBox::warning(this, "保存失败", "无法保存图表,请检查路径或文件权限。");
    }
}

4.扩展:

 然后·····就没有然后啦,就这样,如果想在添加两个按钮实现点击开始按钮开始生成,点击停止按钮就停止生成,这个也简单。定义两个按钮,之后转到槽,将定时器的start()函数设置到这里,就可以控制定时器的开关从而控制图像的生成了

5.总代码

widget.cpp

#include "widget.h" // 包含Widget类的声明
#include "ui_widget.h" // 包含由UI设计器生成的Widget的UI部分
#include "QChartView" // 包含QChartView类,用于显示图表
#include "QChart" // 包含QChart类,用于创建图表
#include "QValueAxis" // 包含QValueAxis类,用于创建值轴
#include "QSplineSeries" // 包含QSplineSeries类,用于创建曲线系列
#include "QTimer" // 包含QTimer头文件,用于定时器
#include <QRandomGenerator> // 用于生成随机数
#include "QMessageBox" // 包含QMessageBox类,用于显示消息框

// Widget类的构造函数
Widget::Widget(QWidget *parent)
    : QWidget(parent) // 调用基类的构造函数
    , ui(new Ui::Widget) // 初始化UI指针
    , time(0) // 初始化时间变量
{
    ui->setupUi(this); // 初始化UI

    // 初始化定时器并连接到 updateChart 槽
    QTimer *timer = new QTimer(this); // 创建定时器
    connect(timer, &QTimer::timeout, this, &Widget::updateChart); // 连接定时器超时信号到槽函数
    timer->start(1000); // 启动定时器,每隔1000毫秒(1秒)触发一次

    // 初始化类成员变量 chart 和 splineSeries
    chart = new QChart(); // 创建图表对象
    splineSeries = new QSplineSeries(); // 创建曲线系列对象

    // 为 splineSeries 添加初始点
    splineSeries->append(0, 0); // 在曲线系列中添加点(0,0)

    QPen pen(QColor(0xff5566)); // 创建一个红色画笔
    splineSeries->setPen(pen); // 设置曲线系列的画笔

    // 将曲线添加到图表
    chart->addSeries(splineSeries); // 将曲线系列添加到图表中

    // 创建坐标轴
    QValueAxis *valueAxisX = new QValueAxis; // 创建X轴
    QValueAxis *valueAxisY = new QValueAxis; // 创建Y轴

    // 设置坐标轴范围
    valueAxisX->setRange(0, 5000); // 设置X轴范围为0到5000
    valueAxisY->setRange(0, 100); // 设置Y轴范围为0到100
    valueAxisX->setTitleText("时间/ms"); // 设置X轴标题
    valueAxisY->setTitleText("温度/°C"); // 设置Y轴标题

    valueAxisX->setLabelFormat("%d"); // 设置X轴标签格式为整数
    valueAxisY->setLabelFormat("%d"); // 设置Y轴标签格式为整数

    // 将坐标轴添加到图表并附加到曲线
    chart->addAxis(valueAxisX, Qt::AlignBottom); // 将X轴添加到图表底部
    chart->addAxis(valueAxisY, Qt::AlignLeft); // 将Y轴添加到图表左侧
    splineSeries->attachAxis(valueAxisX); // 将曲线系列附加到X轴
    splineSeries->attachAxis(valueAxisY); // 将曲线系列附加到Y轴

    // 设置图表标题和图例
    chart->setTitle("温度与时间"); // 设置图表标题
    chart->legend()->setVisible(true); // 显示图例

    // 将图表设置到图表视图中
    ui->chartview->setChart(chart); // 将图表对象设置到ui中的chartview控件
}

// Widget类的析构函数
Widget::~Widget()
{
    delete ui; // 清理UI指针
}

// 更新图表的槽函数
void Widget::updateChart()
{
    qreal randomTemp = QRandomGenerator::global()->bounded(0,100); // 生成0到100之间的随机数作为温度

    time += 1000; // 时间增加1000毫秒

    splineSeries->append(time,randomTemp); // 在曲线系列中添加新点

    QValueAxis *axisX = static_cast<QValueAxis*>(chart->axes(Qt::Horizontal).first()); // 获取X轴
    axisX->setRange(time - 5000, time); // 设置X轴范围,确保显示最近5秒的数据
}

// 按钮点击槽函数
void Widget::on_pushButton_clicked()
{
    // 确保 X 轴显示所有数据
    if (!splineSeries->points().isEmpty()) {
        // 获取曲线中的最小和最大时间值
        qreal minX = splineSeries->points().first().x();
        qreal maxX = splineSeries->points().last().x();

        // 设置X轴范围覆盖所有数据点
        QValueAxis *axisX = static_cast<QValueAxis*>(chart->axes(Qt::Horizontal).first());
        axisX->setRange(minX, maxX);
    }

    // 获取 QChartView 的图像
    QPixmap pixmap = ui->chartview->grab(); // 捕获chartview的图像

    // 保存图像为 PNG 文件到当前项目目录
    QString fileName = "full_chart.png"; // 自定义保存文件名
    if (pixmap.save(fileName)) {
        // 成功保存后显示提示信息
        QMessageBox::information(this, "保存成功", "图表已保存为: " + fileName);
    } else {
        // 如果保存失败,提示错误信息
        QMessageBox::warning(this, "保存失败", "无法保存图表,请检查路径或文件权限。");
    }
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QChartView>
#include <QChart>
#include <QSplineSeries>
#include <QValueAxis>
#include <QTimer>
QT_CHARTS_USE_NAMESPACE

    QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

public slots:
    void updateChart();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QChart *chart;            // 保存图表对象
    QSplineSeries *splineSeries; // 保存曲线对象
    qreal time;               // 保存时间轴上的时间
};

#endif // WIDGET_H

UI文件截图:

槽!!!注意这里有一个重点!!!想起来了

我们使用的控件是QGraphicsView,因为Qt自带的控件中没有我们的QChartView,但是QChartView是QGraphics的子类,所以我们右键QGraphicsView,将他提升为QChartView

这样就能用啦!!!!

 给只偷代码不认真看文档的同学当头一棒 啊哈哈哈哈哈哈哈哈哈哈哈哈哈!!!

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值