项目需求: 温度随时间流逝折线图;
组件: QCharts + 定时器;
重点: QDateTimeAxis Api的应用;常规坐标QValueAxis,这里使用QDateTimeAxis时间轴;
要求:
X 轴为时间,随着时间前进,X轴坐标会相应的变化;
Y轴为温度取值范围(每次取最大值和最小值,这里有个小算法,暂不介绍);
开发工具: Qt Create ,语言C++
Qt版本5.15.2,编译器 msvc2019_32位,组件QCharts(这个需要提前安装,暂不做过多介绍);
项目效果图:
这里图片图片最大上传300贞;
图像可以根据实际数据修改:
代码实现:
pro 文件要加:
QT += charts // 需要重新编译
MainWindow.h 文件如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QScatterSeries>
#include <QDateTimeAxis>
#include <QMainWindow>
#include <QPaintEvent>
#include <QPushButton>
#include <QtCharts/QValueAxis>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
QT_CHARTS_USE_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pBn_Start_clicked();
void on_pBn_Stop_clicked();
void slotTimeout();
private:
Ui::MainWindow *ui;
QDateTimeAxis* daxisX; // X时间轴
QValueAxis* daxisY; // 假设 0-10,这里根据 需求 自己选择量程
QLineSeries* dseries;
QChart* dchart;
QChartView* dchartView;
QTimer *timer;
QScatterSeries* scatterSeries;
bool flag = true;
};
#endif // MAINWINDOW_H
重点: 一定要加 QT_CHARTS_USE_NAMESPACE 命名空间, 不然将下面的命名空间补全;
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QTimer>
// 防止中文乱码
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置X轴坐标
daxisX = new QDateTimeAxis;
daxisX->setTitleText("Time");
daxisX->setTickCount(5); // 设置轴坐标网格数
daxisX->setFormat("h:mm:ss"); // 显示时间格式
QDateTime xMin,xMax; // 设置时间坐标轴范围
xMin = QDateTime::currentDateTime();
xMax = xMin.addSecs(10);
daxisX->setRange(xMin,xMax); // X轴 位 当前 时间
// 设置Y轴坐标
daxisY = new QValueAxis;
daxisY->setTitleText("Temperature(°C)");
daxisY->setRange(0, 10);
daxisY->setTickCount(5); // 设置轴坐标网格数
daxisY->setLabelFormat("%d"); // 格式化为整形
QPen dpen;
dpen.setWidth(3);
dpen.setColor(Qt::red);
dseries = new QLineSeries;
dseries->setName("温度折线图"); // 设置图例名字
//dseries->setPen(pen); // 这里 可以 自定义 折线的颜色
scatterSeries = new QScatterSeries();
scatterSeries->setMarkerSize(8);
dchart = new QChart;
dchart->addSeries(dseries);
dchart->addSeries(scatterSeries);
dchart->setTitle("坐标图");
dchart->setAxisX(daxisX,dseries);
dchart->setAxisY(daxisY,dseries);
dchart->setAxisX(daxisX,scatterSeries); // 折线转点
dchart->setAxisY(daxisY,scatterSeries);
//dchart->legend()->hide(); // 隐藏图例
dchartView = new QChartView(dchart,this);
dchartView->setRenderHint(QPainter::Antialiasing);
dchartView->resize(800,300);
dchartView->move(20,20);
timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, &QTimer::timeout, this, &MainWindow::slotTimeout);
}
void MainWindow::slotTimeout()
{
QDateTime Min,Max; // 设置时间坐标轴范围
int random = qrand()%10;
if(flag) // 确保第一次从原点开始
{
flag=false;
Min = QDateTime::currentDateTime();
Max = Min.addSecs(10);
daxisX->setRange(Min,Max); // X轴 位 当前 时间
dseries->append(Min.toMSecsSinceEpoch(),random);
scatterSeries->append(Min.toMSecsSinceEpoch(),random);
}
QDateTime t(QDateTime::currentDateTime());
dseries->append(t.toMSecsSinceEpoch(),random);
scatterSeries->append(t.toMSecsSinceEpoch(),random);
QDateTime xMax;// 设置时间坐标轴范围
xMax = QDateTime::currentDateTime();
if(xMax > daxisX->max())
{
QDateTime xMin;
xMin = xMax.addSecs(qint64(-10));
daxisX->setRange(xMin,xMax);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pBn_Start_clicked()
{
if (!timer->isActive())
{
timer->start();
}
}
void MainWindow::on_pBn_Stop_clicked()
{
timer->stop();
}
总结: 主要核心思想,每隔一秒 判断当前时间是否大于X轴时间的最大值,如果大于则改变量程(当前时间作为X轴的最大值,最小值为当前时间减去10秒),继续绘图;
由于csdn收费,代码地址放到gitee上了:https://gitee.com/ss103838/pro_-line_-demo.git
如何更优雅的使用轮子;