QT篇之QChart绘制波形图操作(中)

接上篇 QT篇之QChart绘制波形图操作(上)
解决问题一:

在这里插入图片描述

图片来源:Qt 波形绘制相关
本人用的QT自带的QtChart组件,安装QT的时候如果没有勾选这一模块的话可以在QT安装目录下的MaintenanceTool.exe来更新一下,MaintenanceTool.exe使用时要配置Repositories,可以参考这篇博客:Qt5.10_msvc2017 | [Qt维护] 添加、删除和更新组件模块,但是这个工具有bug,如果安装的QT没有QtChart组件的话,卸载重装更省劲儿一些。
然后开始绘制曲线图:
步骤:①配置.pro (QT += charts)② using namespace QtCharts; ③创建QChart(绘图)和QChartView(显示)实例 ④为QChart绑定曲线/折线/散列点序列实例和坐标轴实例 ⑤调用序列的replace函数替换坐标点
可以看这篇博客的QChart Demo Qtchart教程
解决问题二:
曲线用QSplineSeries *splineSeries; //曲线序列
折线用QLineSeries *lineSeries; //折线图数据序列
其实垂线就是一条折线,两点相连成一条直线,所以绘制一条垂线就是添加横坐标相同而纵坐标不同的两个点
解决问题三:
利用项目数据填充曲线/折线序列,可以用
QVector<QPointF> *pointBuffer;           //存储坐标点序列
QQueue<double> *dynPointBuffer;          //存储坐标点序列,用于绘制动态波形
这两种方式,QVector类型替换效率最高,可以用于大数据图表的静态分析,同时可以用队列的方式来实现实时动态曲线(波形),只需合理设置定时器就可实现。
解决问题四:
图表的布局其实是用的QStackedWidget用来实现翻页,并在每个页面内添加QGridLayout的布局。
这里边有一个问题就是如何让QGridLayout布局自动适应父部件QStackedWidget的大小,这里可以将QStackedWidget的布局同样调整为QGridLayout,一般父部件未调整布局都会有一个红色的禁止标志。
解决问题五:
①利用信号和槽机制,当要调整数据时发出要调整的数据信号②槽函数接收到调整后的数据,然后先清除原有的折线数据序列,再将调整后的数据append到折线序列
解决问题六:
建议用部件注册事件的方式来实现,这种方式用起来比较灵活,当然可以根据项目需要重新实现父类的void mouseMoveEvent(QMouseEvent *event)等操作。
//chartView事件过滤封装
void ShowChart::charViewEventFilter(QEvent *event,QChart *tempChart)
{
    if(event->type()==QEvent::Wheel){
        QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event); //将event强制转换为发生的事件的类型
        if(wheelEvent->delta()>0)tempChart->zoom(1.2);
        else tempChart->zoom(10.0/11);
    }
    else if(event->type()==QEvent::MouseButtonPress){
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        if(mouseEvent->button() & Qt::RightButton)
            tempChart->zoomReset();
    }
    else if(event->type()==QEvent::KeyPress){
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        switch (keyEvent->key()) {
        case Qt::Key_Left:
            tempChart->scroll(-20, 0);
            break;
        case Qt::Key_Right:
            tempChart->scroll(30, 0);
            break;
        case Qt::Key_Up:
            tempChart->scroll(0, 30);
            break;
        case Qt::Key_Down:
            tempChart->scroll(0, -20);
            break;
        default:
            keyPressEvent(keyEvent);
            break;
        }
    }
}
下面是部分代码
//事件过滤
bool ShowChart::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == &view[T1X]){
        charViewEventFilter(event,&chart[T1X]);
    }
解决问题七:
利用QSplineSeries的hovered信号
    connect(&splineSeries[0], &QSplineSeries::hovered, this, &ShowChart::slotPointHoverd);
槽函数:
void ShowChart::slotPointHoverd(const QPointF &point, bool state)
{
    if (state) {
        m_valueLabel->setText(QString::asprintf("%1.0f,%1.0f", point.x(),point.y()));
        QPoint curPos = mapFromGlobal(QCursor::pos());
        m_valueLabel->move(curPos.x() - m_valueLabel->width() / 2, curPos.y() - m_valueLabel->height() * 1.5);  
        m_valueLabel->show();
    }
    else {
        m_valueLabel->hide();
    }
}
这里边有一个问题就是可能Label在界面显示不完整或者不在界面的最顶层显示,可以用这种方式
m_valueLabel->raise();
m_valueLabel->setWindowFlag(Qt::WindowStaysOnTopHint);
将其在界面的最顶层显示
解决问题八:
定时器+队列
    connect(drawTimer, SIGNAL(timeout()), this, SLOT(drawDynSplineWave()));
    drawTimer->start(50);
    qDebug()<<"start timer";
void DynamicWave::drawDynSplineWave()
{
    double drawPoint = 0;

    if(readData->dynPointBuffer[T1X].size() != 0){
        drawPoint = readData->dynPointBuffer[T1X].dequeue()/40;          //将纵坐标原始数据缩小40倍        
        splineSeries[T1X].replace(counts,QPointF(counts,drawPoint));

        if(readData->dynPointBuffer[T1X].size() == 0){
            counts = 0;
            drawTimer->stop();
            qDebug()<<"T1 dequeue over";
        }
    }
    counts ++;
}

补充:
这里说一下replace的用法:
void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
Replaces the point with the coordinates oldX and oldY with the point with the coordinates newX and newY. Does nothing if the old point does not exist.
See also pointReplaced().
void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint)
Replaces the point specified by oldPoint with the one specified by newPoint.
See also pointReplaced().
void QXYSeries::replace(int index, qreal newX, qreal newY)
Replaces the point at the position specified by index with the point that has the coordinates newX and newY.
See also pointReplaced().
void QXYSeries::replace(int index, const QPointF &newPoint)
Replaces the point at the position specified by index with the point specified by newPoint.
See also pointReplaced().
void QXYSeries::replace(QList<QPointF> points)
Replaces the current points with the points specified by points.
Note: This is much faster than replacing data points one by one, or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced() when the points have been replaced. However, note that using the overload that takes QVector<QPointF> as parameter is faster than using this overload.
See also pointsReplaced().
void QXYSeries::replace(QVector<QPointF> points)
Replaces the current points with the points specified by points.
Note: This is much faster than replacing data points one by one, or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced() when the points have been replaced.
See also pointsReplaced().
这是我在QT帮助文档上摘录的,可以看到入参为QVector(QPointF)类型的replace方法效率是最高的,比起逐一替换旧点坐标,该方法效率确实突出。另外注意用其他方式替换旧点的时候是一定要存在该旧点坐标,不然会发生索引越界错。
  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
QChart是Qt框架提供的一个绘图工具,它可以用来绘制各种类型的图表,包括波形图绘制波形图通常需要准备好数据,并将数据传递给QChart来绘制曲线。 首先,需要创建一个QChart对象,并将其设置为绘图区域。可以使用QChartView来显示这个图表。然后,创建一个QLineSeries对象,并将数据添加到该系列。可以通过调用addData函数来添加数据点,数据点顺序添加,即曲线的走向是按照数据点的添加顺序来绘制的。可以通过设置线条的颜色、线宽等属性,来调整曲线的样式。 接着,可以创建一个QChartAxis对象,并将其设置为X轴或Y轴。可以通过设置轴线的范围,以及刻度的间隔、格式等属性,来调整轴线的显示。可以通过调用setAxis函数,将轴线添加到图表。 最后,将QLineSeries对象添加到QChart,并在QChartView显示。可以通过调用setRenderHint函数,设置绘制的抗锯齿效果。也可以通过调用setAnimationOptions函数,设置曲线绘制的动画效果。 通过上述步骤,就可以使用QChart绘制波形图。当数据发生变化时,只需要将新的数据添加到QLineSeries对象,然后刷新图表即可。波形图常用于显示实时数据的变化趋势,因此这个过程可以在定时器或者其他事件触发的回调函数进行,以达到实时更新图表的效果。 总结起来,使用QChart绘制波形图的主要步骤包括创建QChart对象、创建QLineSeries对象并添加数据、创建QChartAxis对象并设置轴线属性、将QLineSeries对象添加到QChart、在QChartView显示图表。这样就可以实现简单的波形图绘制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Not found

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值