Qt Charts - 绘制简单曲线图(1)

1 概述

QSplineSeries类是Qt图表模块中的一个曲线系列类,用于绘制平滑的二次和三次曲线。这个系列通过在给定的数据点之间插值来绘制曲线,从而使得曲线更加平滑。
使用QSplineSeries时,需要将数据点作为QPointF类型的列表传递给数据集。然后将数据集添加到QChart中。可以使用QSplineSeries的其他方法来设置线条颜色、宽度、拐点形状等。

2 主要功能

  1. 动态绘制曲线图
  2. 放大、缩小以及还原图表视图
  3. 实时获取图表坐标值

3 功能步骤

3.1 动态曲线图

  1. .pro文件加入模块,charts。
QT       += core gui charts
  1. 在设计师界面拖拽一个QGraphicsView控件,提升为自己重写的MyChartView类。
    在这里插入图片描述
    在这里插入图片描述
  2. MyChartView类以及MainWindow类头文件里加入图表命名空间,以及对应头文件。
#include <QChartView>

QT_CHARTS_USE_NAMESPACE
// 或者 using namespace QtCharts;
  1. 主要代码
// 头文件相关声明
const int AXIS_MIN_X =   0;
const int AXIS_MAX_X =  50;
const int AXIS_MIN_Y = -50;
const int AXIS_MAX_Y =  50;

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private Q_SLOTS:
    void onTimeOut();

private:
    void createChart();  // 创建图表

private:
    Ui::MainWindow *ui;

    QChart *chart;
    QSplineSeries *series;
    QValueAxis *axisX;
    QTimer *timer;
    QRandomGenerator *randGenerator;
    int m_lastY;                        // 记录series上一次y轴值
    bool m_pause;                       // 记录是否暂停绘图
    bool m_start;                       // 记录是否启动绘图
    QLabel *m_labXYValue;
};
// 构造函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_lastY(0)
    , m_pause(false)
    , m_start(false)
{
    ui->setupUi(this);

    timer = new QTimer(this);
    randGenerator = QRandomGenerator::global();
    m_labXYValue = new QLabel("X = , Y = ", this);
    ui->statusbar->addWidget(m_labXYValue);

    createChart(); // 创建图表

    connect(timer, &QTimer::timeout, this, &MainWindow::onTimeOut);
}
// 创建图表
void MainWindow::createChart()
{
    chart = new QChart;
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);

    series = new QSplineSeries;
    series->setName("随机数动态曲线");

    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(2);
    pen.setColor(QColor(30, 144, 255));
    series->setPen(pen);

    chart->addSeries(series);

    axisX = new QValueAxis;
    axisX->setRange(AXIS_MIN_X, AXIS_MAX_X); // 设置坐标轴范围
    axisX->setLabelFormat("%.1f"); // 标签格式
    axisX->setTickCount(6); // 坐标轴刻度的数量
//    axisX->setMinorTickCount(2); // 坐标轴小刻度的数量
    axisX->setMinorGridLineVisible(true);
    axisX->setTitleText("X轴"); //标题

    QValueAxis *axisY = new QValueAxis;
    axisY->setRange(AXIS_MIN_Y, AXIS_MAX_Y);
    axisY->setLabelFormat("%.1f");
    axisY->setTickCount(11);
//    axisY->setMinorTickCount(2);
    axisY->setMinorGridLineVisible(true);
    axisY->setTitleText("Y轴");

    chart->addAxis(axisX, Qt::AlignBottom);
    chart->addAxis(axisY, Qt::AlignLeft);

    series->attachAxis(axisX); // 需在chart->addSeries(series)后
    series->attachAxis(axisY);

    //-----------
    series->append(QPointF(0.0, 0.0));
}

主要的思路就是通过使用定时器并设置一定的间隔,不断往序列添加QPointF。绘制到图表并显示到图表视图上。这里的QPointF是通过Qt的随机数生成器类QRandomGenerator来生成曲线序列y轴值,具体的序列点也可以通过实际采集的数据来进行显示。

// count: 全局静态统计x轴值的变量
void MainWindow::onTimeOut()
{
    timer->stop();
    if(count > AXIS_MAX_X) {
        series->remove(0);
        chart->axes(Qt::Horizontal, series).at(0)->setMin(count - AXIS_MAX_X);
        chart->axes(Qt::Horizontal, series).at(0)->setMax(count);
    }
    int y = randGenerator->bounded(m_lastY - 15, m_lastY + 16);
    if (y < AXIS_MIN_Y) { // 生成的y轴值小于y轴最小值
        y += 15;
    } else if (y > AXIS_MAX_Y) { // 生成的y轴值大于y轴最大值
        y -= 15;
    }
    series->append(QPointF(count, y));
    m_lastY = y; // 记录series上一次y轴值
    count += 2;
    timer->start(300);
}

3.2 放大、缩小以及还原

通过QChart类提供的函数实现

void MainWindow::on_actZoomIn_triggered()
{
    chart->zoom(1.2);
}
void MainWindow::on_actZoomOut_triggered()
{
    chart->zoom(0.8);
}
void MainWindow::on_actZoomReset_triggered()
{
    chart->zoomReset();
}

3.3 实时获取图表坐标值

  1. 在自己的图表视图类里添加自定义鼠标移动信号,以及重写父类鼠标移动事件。
class MyChartView : public QChartView
{
    Q_OBJECT
public:
    explicit MyChartView(QWidget *parent = nullptr);

protected:
    void mouseMoveEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;

signals:
    void mouseMovePoint(QPoint point);
};
  1. 源文件定义

setMouseTracking(true) 将鼠标跟踪设置为true(缺省为false)。如果不设置为true,窗口组件只在某个鼠标按键按下时才接收鼠标移动事件,设置为true 之后,只要鼠标移动就会发射mouseMoveEvent()事件。

MyChartView::MyChartView(QWidget *parent) : QChartView(parent)
{
    setMouseTracking(true);
}

void MyChartView::mouseMoveEvent(QMouseEvent *event)
{
    QPoint point = event->pos();
    emit mouseMovePoint(point);
    QChartView::mouseMoveEvent(event);
}

void MyChartView::wheelEvent(QWheelEvent *event)
{
    // 垂直滚动
    if (event->angleDelta().y() > 0) {
        chart()->zoom(1.2);
    } else {
        chart()->zoom(0.8);
    }
    QChartView::wheelEvent(event);
}
  1. 在窗口类(MainWindow)里连接与MyChartView类的信号槽。
connect(ui->chartView, &MyChartView::mouseMovePoint, this, &MainWindow::onMouseMovePoint);

void MainWindow::onMouseMovePoint(QPoint point)
{
    QPointF pos = ui->chartView->chart()->mapToValue(point);
    m_labXYValue->setText(QString("X = %1, Y = %2")
        .arg(QString::number(pos.x(), 'f', 2))
        .arg(QString::number(pos.y(), 'f', 2)));
}

4 具体效果

在这里插入图片描述

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
qt是一个跨平台的应用程序开发框架,它提供了多种图形绘制功能,其中包括曲线图、柱状图和饼状图。 曲线图是一种用于展示数据趋势和变化的图表类型。在qt中,可以使用Qt Charts模块来创建曲线图。通过指定横轴和纵轴的坐标值,可以将数据点连接起来,并且可以自定义线条的样式、粗细和颜色等。曲线图可以帮助我们分析数据的变化规律,比如趋势是否递增或递减,以及是否存在峰值或谷值等。 柱状图是一种用于比较不同数据之间差异的图表类型。在qt中,可以使用Qt Charts模块来创建柱状图。每个数据点都可以表示为一个条形,其长度与数据的大小成比例。柱状图通常用于比较不同类别或时间的数据,例如销售额、人口统计和学生成绩等。通过柱状图,我们可以直观地了解数据之间的差异,以及它们的相对大小。 饼状图是一种用于展示数据占比的图表类型。在qt中,可以使用Qt Charts模块来创建饼状图。饼状图将数据划分为不同的扇形区域,每个区域的角度大小与数据的占比成比例。饼状图通常用于展示相对比例关系,例如各个产品的销售份额或不同地区的人口比例等。通过饼状图,我们可以直观地了解各个数据项占总体的比例大小。 在qt中,曲线图、柱状图和饼状图都可以根据需求进行自定义,包括图表样式、颜色、数据标签和图例等。它们的创建和显示都相对简单,使得我们可以方便地进行数据分析和展示。无论是用于科学研究、商业决策还是教育培训等领域,这些图表类型都能够提供直观的数据展示方式,帮助我们更好地理解和利用数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值