QCustomPlot 共用X轴多Y轴绘制多条曲线

qcustomplot多个坐标系 继承重写了qcostomplot原有布局样式,添加了部分自定义功能函数。 阅读详情
AI摘要

文章描述了一个使用Qt库进行数据库操作(SQLite)的AttitudeWidget类,包括数据导入、清除、刷新、搜索和姿态数据的绘制。展示了如何使用QComboBox、QTableView、线程以及QCustomPlot进行界面交互和数据处理。

这个参照了一个大佬的代码,时间太久,不记得出处了。

#include "AttitudeWidget.h"
#include "ui_AttitudeWidget.h"

#include "AttitudeWorker.h"

#include <QFileDialog>

#include <QThreadPool>

#include "QCustomPlot/XxwCustomPlot.h"

AttitudeWidget::AttitudeWidget(QSettings* poSet, QWidget* parent) :
    QWidget(parent),
    ui(new Ui::AttitudeWidget), poSet(poSet)
{
    ui->setupUi(this);

    db = QSqlDatabase::addDatabase("QSQLITE", "Main");
    db.setDatabaseName("SIG.db"); //设置数据库名称

    if(!db.isOpen())
    {
        if(!db.open())
        {
            qDebugV0() << "open error:" << db.lastError().text();
            this->recvMsg(db.lastError().text());
            return;
        }
        else
        {
            qDebugV0() << "database connect OK!";
        }
    }
    QSqlQuery query(db);
    query.exec("CREATE TABLE IF NOT EXISTS Attitude(DevId TEXT, "
               "TaskName TEXT, CreateTime TEXT, Timestamp TEXT, "
               "pitch REAL, roll REAL, yaw REAL)");

    this->refresh();

    ui->splitterH->setStretchFactor(0, 2);
    ui->splitterH->setStretchFactor(1, 1);

    ui->splitterV->setStretchFactor(0, 4);
    ui->splitterV->setStretchFactor(1, 1);

    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

AttitudeWidget::~AttitudeWidget()
{
    delete ui;

    db.close();
}

void AttitudeWidget::on_pushButtonImport_clicked()
{
    QString oStrPath = poSet->value("PATH_OPEN").toString();

    if(oStrPath.isEmpty())
    {
        oStrPath = QCoreApplication::applicationDirPath();
    }

    QStringList aoStrFileName = QFileDialog::getOpenFileNames(this, tr("打开姿态文件"),
                                oStrPath,
                                tr("Raw(*_atti*.dat)"));

    foreach(QString oStrFileName, aoStrFileName)
    {

        AttitudeWorker* poWorker = new AttitudeWorker(oStrFileName);
        poWorker->setParent(nullptr);

        connect(poWorker, &AttitudeWorker::sigMsg, this, &AttitudeWidget::recvMsg);

        QThreadPool::globalInstance()->start(poWorker);
    }

    if(!aoStrFileName.isEmpty())
    {
        QFileInfo oFileInfo( aoStrFileName.first() );

        if(! oFileInfo.absolutePath().isEmpty())
        {
            poSet->setValue("PATH_OPEN",  oFileInfo.absolutePath());
        }
    }
}

void AttitudeWidget::on_pushButtonClear_clicked()
{
    QMessageBox::StandardButton standarButton = QMessageBox::question(this,
        "警告",
        "谨慎操作!",
        QMessageBox::Ok | QMessageBox::Cancel,
        QMessageBox::Cancel);
    switch (standarButton)
    {
        case QMessageBox::Ok:
            if(poModel != nullptr)
            {
                poModel->setQuery("delete from Attitude");

                poModel->submit();
            }
            break;
        case QMessageBox::Cancel:

            break;
        default:
            break;
    }
}

void AttitudeWidget::on_pushButtonRefresh_clicked()
{
    this->refresh();
}

void AttitudeWidget::recvMsg(QString oStrMsg)
{
    ui->textBrowser->append(oStrMsg);
}

void AttitudeWidget::refresh()
{
    // 创建模型和映射器
    if(poModel == nullptr)
    {
        poModel = new QSqlQueryModel;
    }
    else
    {
        poModel->clear();
    }

    poModel->setQuery("SELECT * FROM Attitude");
    poModel->setHeaderData(ATTITUDE_TABLE_DEV_ID, Qt::Horizontal, "设备编号");
    poModel->setHeaderData(ATTITUDE_TABLE_TASK_NAME, Qt::Horizontal, "任务名称");
    poModel->setHeaderData(ATTITUDE_TABLE_CREATE_TIME, Qt::Horizontal, "创建时间");
    poModel->setHeaderData(ATTITUDE_TABLE_TIMESTAMP, Qt::Horizontal, "时间戳");
    poModel->setHeaderData(ATTITUDE_TABLE_PITCH, Qt::Horizontal, "俯仰角");
    poModel->setHeaderData(ATTITUDE_TABLE_ROLL, Qt::Horizontal, "横滚角");
    poModel->setHeaderData(ATTITUDE_TABLE_YAW, Qt::Horizontal, "航向角");

    ui->tableView->setModel(poModel);

    ui->tableView->repaint();

    QSqlQuery query(db);

    //设备名称发生变化的时候
    ui->comboBoxDevId->clear();
    query.exec("select DISTINCT DevId from Attitude");
    while(query.next())
    {
        ui->comboBoxDevId->addItem( query.value(0).toString());
    }
    query.clear();
    ui->comboBoxDevId->repaint();

    connect(ui->comboBoxDevId, &QComboBox::currentTextChanged, this, [ = ](QString oStrDevId)
    {
        QSqlQuery query(db);

        ui->comboBoxTaskName->clear();
        query.exec(QString("select DISTINCT TaskName from Attitude where DevId = '%1'").arg(oStrDevId));
        while(query.next())
        {
            ui->comboBoxTaskName->addItem( query.value(0).toString());
        }
        query.clear();
        ui->comboBoxTaskName->repaint();
    });

    //任务名称发生变化的时候
    query.clear();
    ui->comboBoxTaskName->clear();
    query.exec("select DISTINCT TaskName from Attitude");
    while(query.next())
    {
        ui->comboBoxTaskName->addItem( query.value(0).toString());
    }
    query.clear();
    ui->comboBoxCreateTime->repaint();

    connect(ui->comboBoxTaskName, &QComboBox::currentTextChanged, this, [ = ](QString oStrTaskName)
    {
        QSqlQuery query(db);

        ui->comboBoxCreateTime->clear();
        query.exec(QString("select DISTINCT CreateTime from Attitude where DevId = '%1' AND TaskName = '%2' ")
                   .arg(ui->comboBoxDevId->currentText())
                   .arg(oStrTaskName));
        while(query.next())
        {
            ui->comboBoxCreateTime->addItem( query.value(0).toString());
        }
        query.clear();
        ui->comboBoxCreateTime->repaint();
    });

    // Set the resize mode for all columns to ResizeToContents
    for (int col = 0; col < ui->tableView->horizontalHeader()->count(); ++col)
    {
        ui->tableView->horizontalHeader()->setSectionResizeMode(col, QHeaderView::ResizeToContents);
    }

    ui->tableView->repaint();
}


//绘制姿态欧拉角
void AttitudeWidget::drawAttitude(QVector<double> avTimestamp, QVector<QVector<double> > vvdAttitude)
{
    ui->plot->setMinimumSize(QSize(1024, 633));
    ui->plot->setWindowTitle("姿态");
    ui->plot->setWindowIcon(QIcon(":/new/prefix1/image/accelerometer-sensor.png"));
    ui->plot->setWindowModality(Qt::ApplicationModal);

    ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
    ui->plot->plotLayout()->clear();   // 首先清空默认的轴矩形,让我们从头开始

    for(int i = 0; i < 3; ++i)
    {
        QCPAxisRect* volumeAxisRect = new QCPAxisRect(ui->plot);
        ui->plot->plotLayout()->addElement(i, 0, volumeAxisRect);

        QCPAxis* poAxisX = volumeAxisRect->axis(QCPAxis::atBottom);
        QCPAxis* poAxisY = volumeAxisRect->axis(QCPAxis::atLeft);

        //Field
        poAxisX->grid()->setSubGridVisible(true);
        poAxisY->grid()->setSubGridVisible(true);

        volumeAxisRect->setAutoMargins(QCP::msRight | QCP::msTop | QCP::msBottom);
        volumeAxisRect->setMargins(QMargins(100, 0, 0, 0));

        poAxisY->setPadding(0); // 这里的5是你想要的额外填充
        poAxisY->setTickLabelPadding(5); // 这里的5是你想要的额外填充
        poAxisY->setLabelPadding(5); // 这里的5是你想要的额外填充

        poAxisX->setVisible((i == 2) ? true : false);

        QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);//日期做X轴
        dateTicker->setDateTimeFormat("HH:mm:ss.zzz");//日期格式(可参考QDateTime::fromString()函数)
        dateTicker->setTickCount(12);
        poAxisX->setTicker(dateTicker);//设置X轴为时间轴

        QList<QCPAxis*> aaxisField;
        aaxisField << poAxisX;
        volumeAxisRect->setRangeZoomAxes(aaxisField);

        poAxisY->setVisible(true);
        poAxisY->setLabel(CONST_ATTITUDE.at(i));

        auto poGraph = ui->plot->addGraph(poAxisX, poAxisY);
        poGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 5));
        poGraph->setName(CONST_ATTITUDE.at(i));
        poGraph->setData(avTimestamp, vvdAttitude.at(i));
        poGraph->setLineStyle(QCPGraph::lsLine);
        //poGraphEx->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 8));
        poGraph->setPen(QPen(Qt::blue, 2));

        poGraph->rescaleKeyAxis(true);
        poGraph->rescaleValueAxis(true, true);
        poGraph->rescaleAxes();

        auto poThread = new QThread;
        poGraph->setParent(nullptr);
        poGraph->moveToThread(poThread);
        poGraph->setVisible(true);
    }

    for(int i = 0; i < 3; ++i)
    {
        QCPAxisRect* poRecti = (QCPAxisRect*)ui->plot->plotLayout()->element(i, 0);
        for(int j = 0; j < 3; ++j)
        {

            if(i != j)
            {
                QCPAxisRect* poRectj = (QCPAxisRect*)ui->plot->plotLayout()->element(j, 0);

                connect(poRecti->axis(QCPAxis::atBottom), QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged),
                        poRectj->axis(QCPAxis::atBottom), QOverload<const QCPRange&>::of(&QCPAxis::setRange));
            }
        }
    }

    ui->plot->replot();
}

//查询
void AttitudeWidget::on_pushButtonSearch_clicked()
{
    QSqlQuery query(db);

    poModel->setQuery(QString("SELECT * FROM ATTITUDE WHERE DevId = '%1' AND TaskName = '%2' AND CreateTime = '%3'" )
                      .arg(ui->comboBoxDevId->currentText())
                      .arg(ui->comboBoxTaskName->currentText())
                      .arg(ui->comboBoxCreateTime->currentText()));

    ui->tableView->setModel(poModel);

    ui->tableView->repaint();

    query.exec(QString("SELECT timestamp, pitch, roll, yaw FROM ATTITUDE WHERE DevId = '%1' AND TaskName = '%2' AND CreateTime = '%3'" )
               .arg(ui->comboBoxDevId->currentText())
               .arg(ui->comboBoxTaskName->currentText())
               .arg(ui->comboBoxCreateTime->currentText()));

    QVector<double> avTimestamp;
    QVector<QVector<double> > vvdAttitude;
    QVector<double> avPitch;
    QVector<double> avRoll;
    QVector<double> avYaw;

    while(query.next())
    {
        double dSec = QDateTime::fromString(query.value(0).toString(), "yyyy年MM月dd日 HH:mm:ss.zzz").toMSecsSinceEpoch() / 1000.0;

        this->recvMsg(QString("timestamp: %1\tpitch: %2\troll: %3\tyaw: %4")
                      .arg(query.value(0).toString())
                      .arg(query.value(1).toDouble())
                      .arg(query.value(2).toDouble())
                      .arg(query.value(3).toDouble()));

        avTimestamp.append(dSec);
        avPitch.append(query.value(1).toDouble());
        avRoll.append(query.value(2).toDouble());
        avYaw.append(query.value(3).toDouble());
    }
    vvdAttitude.append(avPitch);
    vvdAttitude.append(avRoll);
    vvdAttitude.append(avYaw);

    this->drawAttitude(avTimestamp, vvdAttitude);

    query.clear();
}

void AttitudeWidget::on_pushButtonClearLog_clicked()
{
    ui->textBrowser->clear();
}

另外一个地方也用到了,代码差不多。算是个记录。

#include "MultiAxisWidget.h"
#include "ui_MultiAxisWidget.h"

#include "QCustomPlot/XxwCustomPlot.h"

MultiAxisWidget::MultiAxisWidget(int iCnt, QWidget *parent) :
    QWidget(parent), ui(new Ui::MultiAxisWidget), iCnt(iCnt)
{
    ui->setupUi(this);

    ui->plot->setWindowTitle("曲线对比");
    ui->plot->setWindowIcon(QIcon(":/new/prefix1/image/multiple.png"));
    ui->plot->setMinimumSize(QSize(1000, 618));
    ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);

    ui->plot->plotLayout()->clear();   // 首先清空默认的轴矩形,让我们从头开始,这一行语句之后,就不要有任何 plot操作了!都清除了。

    QGridLayout *poGrid = new QGridLayout;

    poStatusBar = new QStatusBar;
    poStatusBar->showMessage("单击曲线,显示对应时域文件标签。");

    QVBoxLayout *poHLayout = new QVBoxLayout;

    poHLayout->insertWidget(0, ui->plot, 1);
    poHLayout->insertWidget(1, poStatusBar, 0);

    poGrid->addLayout(poHLayout, 0, 0, Qt::AlignCenter);

    this->setLayout(poGrid);

    iCntIndex = 0;
}

MultiAxisWidget::~MultiAxisWidget()
{
    delete ui;
}

void MultiAxisWidget::recvRawData(int iRow, QString oStrLabel, QVector<double> adX, QVector<double> adY)
{
    QCPAxisRect *volumeAxisRect = new QCPAxisRect(ui->plot);
    ui->plot->plotLayout()->addElement(iCntIndex, 0, volumeAxisRect);

    QCPAxis *poAxisX = volumeAxisRect->axis(QCPAxis::atBottom);
    QCPAxis *poAxisY = volumeAxisRect->axis(QCPAxis::atLeft);

    poAxisY->grid()->setZeroLinePen(QPen(Qt::red));

    //Field
    poAxisX->grid()->setSubGridVisible(true);
    poAxisY->grid()->setSubGridVisible(true);

    volumeAxisRect->setAutoMargins(QCP::msRight | QCP::msTop | QCP::msBottom);
    volumeAxisRect->setMargins(QMargins(100, 0, 0, 0));

    poAxisY->setPadding(0); // 这里的5是你想要的额外填充
    poAxisY->setTickLabelPadding(5); // 这里的5是你想要的额外填充
    poAxisY->setLabelPadding(5); // 这里的5是你想要的额外填充

    poAxisX->setVisible(false);

    // QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);//日期做X轴
    // dateTicker->setDateTimeFormat("HH:mm:ss");//日期格式(可参考QDateTime::fromString()函数)
    // dateTicker->setTickCount(12);
    // poAxisX->setTicker(dateTicker);//设置X轴为时间轴

    QList<QCPAxis *> aaxisField;
    aaxisField << poAxisX;
    volumeAxisRect->setRangeZoomAxes(aaxisField);

    poAxisY->setVisible(true);
    poAxisY->setLabel(oStrLabel);

    auto poGraph = ui->plot->addGraph(poAxisX, poAxisY);

    poGraph->setName(oStrLabel);
    poGraph->setData(adX, adY);
    poGraph->setLineStyle(QCPGraph::lsLine);
    //poGraphEx->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 8));
    poGraph->setPen(QPen(Qt::blue, 2));

    poGraph->rescaleKeyAxis(true);
    poGraph->rescaleValueAxis(true, true);
    poGraph->rescaleAxes();

    auto poThread = new QThread;
    poGraph->setParent(nullptr);
    poGraph->moveToThread(poThread);
    poGraph->setVisible(true);

    ++iCntIndex;

    if(iCntIndex == iCnt)
    {
        QTimer::singleShot(1000, this, [ = ]()
        {
            this->linkage();
        });
    }

    ui->plot->replot();
}

//多  x轴联动
void MultiAxisWidget::linkage()
{
    for(int i = 0; i < iCnt; ++i)
    {
        QCPAxisRect *poRecti = (QCPAxisRect *)ui->plot->plotLayout()->element(i, 0);
        for(int j = 0; j < iCnt; ++j)
        {
            if(i != j)
            {
                QCPAxisRect *poRectj = (QCPAxisRect *)ui->plot->plotLayout()->element(j, 0);

                connect(poRecti->axis(QCPAxis::atBottom), QOverload<const QCPRange &>::of(&QCPAxis::rangeChanged),
                        poRectj->axis(QCPAxis::atBottom), QOverload<const QCPRange &>::of(&QCPAxis::setRange));
            }
        }
    }

    //鼠标单击曲线,在statusBar上展示文件名
    connect(ui->plot, &QCustomPlot::plottableClick, this, [ = ](QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent * event)
    {
        poStatusBar->showMessage(plottable->name());
    });

    //鼠标双击曲线,在颜色对话框中给被点击的曲线设置颜色
    connect(ui->plot, &QCustomPlot::plottableDoubleClick, this, [ = ](QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent * event)
    {
        QColorDialog colorDialog;
        colorDialog.setCurrentColor(Qt::red);

        // 显示对话框
        int result = colorDialog.exec();

        // 检查用户是否选择了颜色
        if (result == QDialog::Accepted)
        {
            // 获取选择的颜色
            QColor selectedColor = colorDialog.selectedColor();

            plottable->setPen(QPen(selectedColor, 2));

            ui->plot->replot();
        }
    });

    ui->plot->replot();
}

QCustomPlot实现鼠标移到曲线上,显示坐标点(支持多条曲线) 本文的整体思路为:在鼠标移动事件中,对鼠标所在的点进行判断,该点的x、y是否在距离曲线的2的像素点范围内,如果在,则显示符合条件的曲线坐标(注意:只能显示往曲线中加入的点信息,即addData、setData,并不是所有的点都能显示出来。如果知道曲线的方程,则可以直接将点带入方程判断是否符合)近期需要实现这个需求,所以进行了研究,共有三种方案,在此记录,初步写了实现,代码还有很多可以优化的地方。有什么问题请大家指出。此方案只实现了针对一幅图的方案,并未和方案一一样,多个曲线判断。 阅读详情

相关推荐

QCustomPlot基础教程(二)——在Qt中绘制多个曲线

目录1.前言2. 经过上一节的基础介绍,相信对QCustomPlot有了基本了解,本文将介绍QCustomPlot的另外一个实例——在Qt上绘制多条曲线。 1.前言 基础部分就不过多介绍了,不懂得可以直接参考:QCustomPlot基础教程(一)——QCustomPlot的安装及基础实例,直接上代码。 2. ...

Wendy的博客 1万+

在python中用QCustomPlot实现多y轴多曲线

它会导致完整的重新插入内部缓冲区。当您对图形的轴范围或数据点进行更改时,必须调用此方法,这使得更改可见。,当我点击左侧窗格(树状视图)时会显示图表。问题是图表在我调整分割器大小之前没有显示或更新。这中间遇到另一个问题,绘图不更,我正在使用。

人太健忘了,需要有个地方记录 3358

项目记录 - Qt QCustomPlot 实时动态数据曲线图,以时间为X轴,数据为Y轴(一)

QCustomPlot的基础参考此作者的文章 https://my.oschina.net/u/4231862/blog/3118155 项目要求: 以时间为X轴,不断更新 Y轴为数据 可选择显示的数据 数据观测,可暂停滚动,Y轴区间变化 ...

qq_38159549的博客 1万+

QCustomPlot单多坐标系显示

1 可进行单坐标系多坐标系的切换2点击QTableWidget的checkbox可以控制坐标系的数量并显示相应的曲线3 在多坐标系中显示游标4 更改曲线的颜色5 坐标系X轴同步 6 曲线的放大缩小、左右移动、上下移动7 创建单X轴多Y轴坐标系

不知东方之既白 5175

QCustomPlot基础教程(三)——在Qt中绘制多条曲线(拓展)

上一节介绍了Qt中多个曲线绘制的基本方法,本文对其进行拓展,介绍多条曲线绘制时如何自动更改颜色以及自动更改线条类型的方法。 目录1、前言2、代码示例3、运行结果4、解释说明 1、前言 基础部分就不过多介绍了,不懂得可以直接参考:QCustomPlot基础教程(一)——QCustomPlot的安装及基础实例,直接上代码。 2、代码示例 代码如下: QCustomPlot *customPlot = ui->customPlot;//创建customPlot QPen pen; QStri

Wendy的博客 1万+

【QCustomPlot】绘制 x-y 曲线图

绘制 x-y 曲线图所使用的类为QCPGraph,它提供的类方法可在中找到。// 重置/添加绘图数据的接口// 设置线型// 设置点型。

m0_37803477的博客 3770

QCustomPlot设置多段Y轴的方法

【代码】QCustomPlot设置多段Y轴的方法。

白鱼儿的博客 1685

【QCustomPlot】1.4 - 绘制动态曲线、波形图,隐藏曲线graph,鼠标移动拖动、滚轮缩放、点击选中

使用Q绘制动态曲线 更多QCustomPlot控件的使用操作,会在本专栏的后续篇章介绍,一起学习进步。 工程已同步至GitHub,欢迎下载学习。使用时记得遵循GPLv3哦。 我的学习例程仓库,GitHub:QCustomPlot 学习例程下载 鼠标缩放,左键拖动缩放,滚轮按鼠标位置整体缩放,右键移动 加载/导出cvs文件 专栏不错哦:https://www.cnblogs.com/swarmbees/category/908110.html ...

Mark_md的博客 1万+

QCustomPlot多个y轴一个x轴、实时绘制多条曲线

一、项目中结合树形目录勾选框,进行动态增加和删除勾选框,通过定时器模拟数据进行显示。4、//当鼠标放大缩小上下移动时 ,多段y轴x轴同步。3、x轴y轴数据同步,当放大缩小表格时;1、动态增加channel所对应的坐标系。2、动态删除channel所对应的坐标系。5、初始化QCustomPlot。2、多段y轴,共用同一个x轴;3、//多段y轴共用同一个x轴。1、动态增加/移除坐标系;

weixin_45074487的博客 5677

QCustomPlot 曲线各种属性详细介绍

图表曲线作为一种直观分析的工具,在软件的应用中非常广泛,我在Qt的应用软件中一直使用QCustomPlot第三方类库,最近因为肺炎疫情一直在家办公,正好抽个时间整理一下QCustomPlot经常使用的属性,省得自己花精力去查阅。 1. legend 设置图例字体、大小、是否显示: QFont font; font.setPixelSize(12);//文字像素大小 font....

luanl的博客 1万+

QCustomPlot基础教程(四)——利用QCustomPlot绘制柱状图

目录一、基础柱状图绘制二、扩展1——横向柱状图的绘制方法 一、基础柱状图绘制 代码示例: //绘制柱状图 QCPAxis *xAxis = ui->customPlot->xAxis;//x轴 QCPAxis *yAxis = ui->customPlot->yAxis;//y轴 QCPBars *bars = new QCPBars(xAxis, yAxis); // 使用xAxis作为柱状图的x轴,yAxis作为y轴 bars->setAntialiased(fals

Wendy的博客 9619

QCustomPlot系列(2)-绘制两条曲线+自动全显+鼠标拖放+rescaleAxes()函数简介

如下图所示:官网给出了几个最简单的绘图示例,位于Basic plotting: 接下来我们将以官网给出的绘制两条曲线为例,看看QCustomPlot的用法。先看下效果图 首先在ui中拖出一个QWidget,命名为customPlot,然后右击提升为QCustomPlot,然后添加代码: 以下代码是官网的,我把注释修改成了中文: MainWindow::MainWindow(QW...

野生猿-群号1025127672 1万+

qcustomplot 绘制 频谱图 瀑布图,游标实现跟随曲线数据的实时展示

标题qcustomplot 绘制 频谱图 瀑布图,游标实现跟随曲线数据的实时展示 文件结构 pri文件结构 重写qcustomplot #ifndef SPECTRUMDISPLAY_H #define SPECTRUMDISPLAY_H #include #include #include<qpainter.h> #include #include<qcustomplot/qcustomplot.h> #include #include class SpectrumDispl

weixin_37594197的博客 6360

QCustomPlot 一个X轴多个Y轴

目标。

小泥人日常 3827

示例qcustomplot多条曲线多个Y轴.cpp

示例qcustomplot多条曲线多个Y轴.cpp

qcustomplot多坐标系

一个qcustomplot对象中多个坐标系,可动态添加,公用X轴,双击修改颜色

使用QCustomplot完成多Y轴曲线绘制

使用QCustomplot完成多Y轴曲线绘制 【下载地址】使用QCustomplot完成多Y轴曲线绘制 使用QCustomplot完成多Y轴曲线绘制本资源文件提供了一个使用QCustomplot库完成多Y轴曲线绘制的示例代码和详细说明 ...

gitblog_09721的博客 455

基于qcustomplot实现多坐标系写入值

对qcustomplot实现多个坐标轴,对4g网络通信提供友好支持

上一篇: Qt C++ 数据预处理笔记(4)——高通滤波
下一篇: Qt C++ chartdir学习 demo
QQ_278397935
博客等级 码龄18年 120粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值