qwt实时波形,标记特征点。

项目是利用qwt展示实时波形。目前需要添加一个功能:在特殊的点,做一个方块或者其他特殊的标记。例如血氧波形,在每一个周期的三个部分做标记。下位机在需要做标记的点位发送1,无需标记的点位发送0;如下图所示:

img

注:本人刚入门不久,可能需朋友们敲好的源码才能看得懂。

参考GPT和自己的思路,以下是一个的 C++ 代码示例,用于在 Qwt 实时波形上添加标记。示例代码基于 Qt5 和 Qwt6,但是可以根据您的版本进行适当的调整。

假设您的波形数据是通过一个 QwtPlotCurve 对象进行绘制的。在下面的代码中,我们将为该曲线添加一个名为 markers 的新数据项,用于在需要添加标记的点位上显示标记。

#include <QTimer>
#include <QVector>
#include <QPointF>
#include <QwtPlot>
#include <QwtPlotCurve>

class MyPlot : public QwtPlot
{
    Q_OBJECT

public:
    MyPlot(QWidget *parent = nullptr)
        : QwtPlot(parent)
        , m_curve(nullptr)
    {
        // 创建曲线对象
        m_curve = new QwtPlotCurve("My Curve");
        m_curve->attach(this);

        // 创建数据数组
        m_data.resize(1000);
        for (int i = 0; i < m_data.size(); i++) {
            m_data[i].setX(i);
            m_data[i].setY(0);
        }

        // 添加标记数据项
        m_markers.resize(m_data.size());
        for (int i = 0; i < m_markers.size(); i++) {
            m_markers[i].setX(i);
            m_markers[i].setY(0);
        }
        m_curve->setData(m_data + m_markers);

        // 启动定时器
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &MyPlot::updateData);
        timer->start(50);
    }

public slots:
    void updateData()
    {
        // 从下位机获取数据
        bool is_marked = getMarkFlag();

        // 更新数据数组
        for (int i = 0; i < m_data.size(); i++) {
            m_data[i].setY(qrand() % 100);
        }

        // 更新标记数据项
        QPointF marker_value(0, 0);
        if (is_marked) {
            marker_value.setY(100);
        }
        for (int i = 0; i < m_markers.size(); i += 3) {
            m_markers[i] = marker_value;
        }

        // 更新曲线数据
        m_curve->setData(m_data + m_markers);
        replot();
    }

private:
    QwtPlotCurve *m_curve;
    QVector<QPointF> m_data;
    QVector<QPointF> m_markers;

    bool getMarkFlag()
    {
        // TODO: 从下位机获取标记数据
        return (qrand() % 10) < 2;
    }
};

在上面的代码中,我们为波形数据数组 m_data 和标记数据数组 m_markers 分别创建了一个长度为 1000 的 QPointF 数组。然后,我们将标记数据数组添加到曲线的数据项中,并在定时器的回调函数中更新数据。每当需要在某个点位添加标记时,我们将该点位在标记数据数组中对应的 QPointF 对象的 Y 坐标设置为 100。

这里假设血氧波形的周期长度为 3,因此每隔 3 个数据点就会添加一个标记。
回答不易,还请采纳!!!

https://www.cnblogs.com/xihong2014/p/17045455.html 参考下。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
您好,要在实时波形上标记特征点,可以使用QwtPlotMarker类。这个类可以在绘图区域上添加标记,并且可以自定义标记的外观和位置。

以下是一个简单的示例代码,它演示了如何在实时波形上添加标记。该代码假设您已经将实时数据绘制在QwtPlot中,并且有一个线程从下位机获取数据并实时更新绘图。

#include <QApplication>
#include <QTimer>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // 创建 QwtPlot 对象和 QwtPlotCurve 对象
    QwtPlot plot;
    QwtPlotCurve curve("实时波形");
    curve.attach(&plot);

    // 创建 QwtPlotMarker 对象并设置其属性
    QwtPlotMarker marker;
    marker.setLineStyle(QwtPlotMarker::VLine);
    marker.setLinePen(QPen(Qt::red, 1, Qt::DashLine));
    marker.attach(&plot);

    // 模拟数据更新线程
    QTimer dataTimer;
    QObject::connect(&dataTimer, &QTimer::timeout, [&]() {
        // 从下位机获取数据
        int value = getDataFromDevice();

        // 更新实时波形
        curve.setData(xData, yData);
        plot.replot();

        // 在特定位置添加标记
        if (value == 1) {
            double xPos = getMarkerPosition();
            marker.setX(xPos);
            marker.setYAxis(QwtPlot::yLeft);
            marker.attach(&plot);
        }
    });
    dataTimer.start(100); // 每 100 毫秒更新一次数据

    plot.show();
    return app.exec();
}


这个示例中,我们创建了一个QwtPlot对象和一个QwtPlotCurve对象来绘制实时波形。然后,我们创建了一个QwtPlotMarker对象,它被设置为垂直线,并且使用红色虚线作为线型。在数据更新时,我们更新实时波形,然后根据从下位机获取的数据决定是否在特定位置添加标记。如果数据值为1,我们获取标记的位置,并将标记添加到QwtPlot中。
·
您需要根据自己的应用程序修改代码,并根据下位机发送的数据来确定标记的位置。

参考GPT和自己的思路:这里是一个利用Qwt实时波形并标记特殊点的简单代码示例:

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QFrame, QApplication, QGridLayout, QLabel
from PyQt5.QtGui import QColor, QPainter
import numpy as np
import sys
import qwt

class MyPlot(qwt.QwtPlot):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.curve = qwt.QwtPlotCurve()
        self.curve.setPen(QColor('blue'))
        self.curve.attach(self)

        self.marker = qwt.QwtPlotMarker()
        self.marker.setValue(0.0, 0.0)
        self.marker.setLineStyle(qwt.QwtPlotMarker.VLine)
        self.marker.setLinePen(QColor('red'), 2, qwt.Qt.DotLine)
        self.marker.attach(self)

        self.data = np.zeros(100)
        self.x = np.arange(100)
        self.update_timer = QTimer(self)
        self.update_timer.timeout.connect(self.update_data)
        self.update_timer.start(100)

    def update_data(self):
        # generate some random data
        new_value = np.random.rand() * 10 - 5
        self.data = np.roll(self.data, -1)
        self.data[-1] = new_value
        self.curve.setData(self.x, self.data)
        self.replot()

        # check if we need to mark a special point
        special_points = [10, 20, 30, 40, 50]
        current_index = len(self.x) - 1
        if current_index in special_points:
            self.marker.setVisible(True)
        else:
            self.marker.setVisible(False)

class MyFrame(QFrame):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.plot = MyPlot(self)
        layout = QGridLayout(self)
        layout.addWidget(self.plot, 0, 0)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    frame = MyFrame()
    frame.show()
    app.exec_()

该示例中定义了一个自定义的Qwt绘图区域MyPlot,绘制了一个实时波形和一个特殊点的标记器。MyPlot每隔100毫秒生成一些随机数据,更新实时波形,然后检查当前的点是否是特殊点,如果是,则显示标记器。

您可以根据您的需求修改这个示例,例如将随机数据生成更改为从下位机接收数据,将特殊点更改为接收到标记信号的位置等等。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
要在Qwt实时波形上标记特征点,可以使用Qwt的Symbol构件。您需要为需要标记的点提供一个信号,以便在该点处添加Symbol。 如果下位机发送1表示标记特殊点,则在该点处添加一个Symbol。首先需要在plot中定义symbol列表,并在特定时间添加QwtSymbol:

    # 定义symbol列表
    self.symbolList = []
    # 定义新的symbol
    markerSymbol = Qwt.QwtSymbol(Qwt.QwtSymbol.Rect,
                                 QBrush(Qt.blue), QPen(Qt.red), QSize(3, 3))
    # 添加到symbol列表
    self.symbolList.append(markerSymbol)
    ...
    # 添加Symbol到画布
    index = ... # 特殊点位的索引
    if receive_data == 1:
        markerSymbol = self.symbolList[0] # 选择需要的symbol,此处使用第一个
        curveData = self.curve.data()
        dx = curveData.xData()[1] - curveData.xData()[0]
        xPos = curveData.xData()[index]
        yPos = curveData.yData()[index]
        # 添加symbol到画布
        marker = Qwt.QwtPlotMarker()
        marker.setValue(QPointF(xPos, yPos))
        marker.setSymbol(markerSymbol)
        marker.attach(self.plot)
        self.plot.replot()

在上述代码中,我们首先定义了一个Symbol列表。Symbol是用于绘制特殊的形状、点等。所以,此处我们定义的Symbol是矩形。然后,根据特殊点的标志位,选择需要的Symbol,获取该特殊点的位置信息,设置Symbol的位置和形状,并将其添加到绘图中。

注意:这里用的是矩形形状,如果你想要其他形状,可以修改QwtSymbol的第一个参数。

完整代码:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy
from PyQt5.QtGui import QBrush, QColor, QPen
from PyQt5.QtCore import Qt, QPointF
import numpy as np
import random
import time
import Qwt as Qwt

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle('Qwt 示例')

        self.plot = Qwt.QwtPlot(self)
        self.plot.setCanvasBackground(Qt.white)
        self.plot.setTitle('实时波形')
        self.plot.setAxisTitle(Qwt.QwtPlot.xBottom, '时间 (s)')
        self.plot.setAxisTitle(Qwt.QwtPlot.yLeft, '幅值 (V)')
        self.plot.setAxisScale(Qwt.QwtPlot.yLeft, -5, 5)
        self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10)
        self.plot.replot()

        # 定义曲线
        self.curve = Qwt.QwtPlotCurve()
        self.curve.attach(self.plot)

        # 定义symbol列表
        self.symbolList = []
        # 定义新的symbol
        markerSymbol = Qwt.QwtSymbol(Qwt.QwtSymbol.Rect,
                                     QBrush(Qt.blue), QPen(Qt.red), QSize(3, 3))
        # 添加到symbol列表
        self.symbolList.append(markerSymbol)

        self.data = {'x': [], 'y': []}

    def generate_data(self):
        x = np.linspace(0, 10, 100)
        y = []
        for i in range(100):
            if i < 20:
                y.append(random.uniform(0, 1))
            elif i < 60:
                y.append(random.uniform(-1, 0))
            else:
                y.append(random.uniform(0, 1))

        self.data['x'] = x.tolist()
        self.data['y'] = y

    def update_plot(self):
        self.generate_data()

        self.curve.setData(self.data['x'], self.data['y'])
        # 添加Symbol到画布
        for index, receive_data in enumerate(self.symbol_signal):
            if receive_data == 1:
                markerSymbol = self.symbolList[0] # 选择需要的symbol,此处使用第一个
                curveData = self.curve.data()
                dx = curveData.xData()[1] - curveData.xData()[0]
                xPos = curveData.xData()[index]
                yPos = curveData.yData()[index]
                # 添加symbol到画布
                marker = Qwt.QwtPlotMarker()
                marker.setValue(QPointF(xPos, yPos))
                marker.setSymbol(markerSymbol)
                marker.attach(self.plot)

        self.plot.replot()

    def start(self):
        self.symbol_signal = [0] * 100
        timer = Qwt.QwtTimer()
        timer.setInterval(20)
        timer.timeout.connect(self.update_plot)
        timer.start()

    def onReceive(self, receive_data):
        self.symbol_signal.append(receive_data)
        self.symbol_signal.pop(0)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()

    # 模拟数据接收
    for index in range(100):
        receive_data = random.randint(0, 1)
        mainWindow.onReceive(receive_data)
        time.sleep(0.1)

    mainWindow.start()

    sys.exit(app.exec_())

到这里,我们就可以在Qwt实时波形上标记出特殊点,并且形状可以自定义。
如果我的回答解决了您的问题,请采纳!