当前位置: 首页 > news >正文

QCustomPlot安装及demo

        QCustomPlot 是一个用于在 Qt 应用程序中创建 2D 绘图和图形的 C++ 类库,它为开发者提供了丰富且便捷的绘图功能.本文主要介绍了QCustomplot的安装及基本使用方法.(版本 Qt 5.14.1及QCustomPlot: Version 2.1.1)

 1.运行结果

        运行结果如图 ,下图的多通道分析图是便是利用QCustomplot提升形成.整个demo模拟画出了三个不同颜色的曲线,同时设计了滚轮放大缩小以及十字坐标显示以及右键截图等功能.

       

2.QCustomPlot下载安装

        在官网上下载所需要版本的QCustomPlot的压缩包QCustomPlot.tar.gz

        官网地址:https://www.qcustomplot.com 

        下载后进行解压,得到h文件和c文件

3.添加到项目

        a.新建qt项目,按照平时的习惯构建即可

        

        b.将qcustomplt的头文件和源文件复制到目录下进行添加,下图为添加成功

        c.添加变量,如果你的QT版本是5.0及以上,我所使用的Qt为5.14.2,那么.pro文件中的QT变量必须添加一个printsupport,添加完成之后,保存一下,如图所示

         

         d.操作得到QCustomPlot控件(注:QCustomPlot是继承自 QWidget 的,使用时,首先生成一个QWidget控件,然后右键点击这个控件,选择提升为QCustomPlot,这样我们就得到了一个可操作的 QCustomPlot 控件)

        

        

4.项目运行

 

        至此,安装和配置QCustomplot步骤全部完成.

5.demo源码

        注释详细

        mianwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "qcustomplot.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

protected:
    bool eventFilter(QObject *obj, QEvent *event) override;

private:
    Ui::MainWindow *ui;

    // 十字线成员变量
    QCPItemStraightLine *crosshairH; // 水平十字线
    QCPItemStraightLine *crosshairV; // 垂直十字线
    QCPItemText *coordText;          // 坐标显示文本

    // 初始化函数
    void setupCustomPlot();          // 初始化图表
    void setupInteractions();        // 初始化交互功能

    // 右键菜单函数
    void showContextMenu(const QPoint &pos);
};
#endif // MAINWINDOW_H

        mianwindow.c文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //初始化图表
    setupCustomPlot();
    //初始化交互功能
    setupInteractions();
}

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

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == ui->widget && event->type() == QEvent::Wheel)
    {
        QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
        if (QApplication::keyboardModifiers() & Qt::ControlModifier)
        {
            double factor = wheelEvent->angleDelta().y() > 0 ? 0.85 : 1.15; // 缩放因子

            ui->widget->xAxis->scaleRange(factor, ui->widget->xAxis->range().center());
            ui->widget->yAxis->scaleRange(factor, ui->widget->yAxis->range().center());
            ui->widget->replot();
            return true;
        }
    }
    return QMainWindow::eventFilter(obj, event);
}

void MainWindow::setupCustomPlot()
{
    QCustomPlot *customPlot = ui->widget;

    // ============ 1. 图表基本设置 ============
    // 设置背景色
    customPlot->setBackground(QBrush(QColor(245, 245, 245)));

    // 添加标题
    customPlot->plotLayout()->insertRow(0);
    QCPTextElement *title = new QCPTextElement(customPlot, "多通道信号分析", QFont("微软雅黑", 12, QFont::Bold));
    customPlot->plotLayout()->addElement(0, 0, title);

    // ============ 2. 创建多条曲线 ============
    customPlot->addGraph(); // 通道1
    customPlot->addGraph(); // 通道2
    customPlot->addGraph(); // 通道3

    // ============ 3. 设置曲线样式 ============
    // 通道1:红色实线,带圆形数据点
    customPlot->graph(0)->setPen(QPen(QColor(255, 50, 50), 1.5));
    customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));
    customPlot->graph(0)->setName("ECG信号");

    // 通道2:绿色虚线,带方形数据点
    QPen greenPen(QColor(50, 180, 50), 1.5);
    greenPen.setStyle(Qt::DashLine);
    customPlot->graph(1)->setPen(greenPen);
    customPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssSquare, 5));
    customPlot->graph(1)->setName("EMG信号");

    // 通道3:蓝色点线,带菱形数据点
    QPen bluePen(QColor(50, 50, 255), 1.5);
    bluePen.setStyle(Qt::DotLine);
    customPlot->graph(2)->setPen(bluePen);
    customPlot->graph(2)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDiamond, 5));
    customPlot->graph(2)->setName("EEG信号");

    // ============ 4. 生成模拟生物信号数据 ============
    QVector<double> x(500), y0(500), y1(500), y2(500);
    for (int i = 0; i < 500; ++i)
    {
        x[i] = i * 0.1; // 20ms采样间隔

        // ECG信号 (模拟心电)
        y0[i] = 1.5 * qSin(i * 0.1) + 0.3 * qSin(i * 0.5) + (qrand() % 100) * 0.01;

        // EMG信号 (模拟肌电)
        y1[i] = 0.8 * qCos(i * 0.15) + (qrand() % 100) * 0.05 - 2;

        // EEG信号 (模拟脑电)
        y2[i] = 0.5 * qSin(i * 0.05) + 0.2 * qCos(i * 0.3) + (qrand() % 100) * 0.02 + 2;
    }

    // 设置数据
    customPlot->graph(0)->setData(x, y0);
    customPlot->graph(1)->setData(x, y1);
    customPlot->graph(2)->setData(x, y2);

    // ============ 5. 坐标轴设置 ============
    // X轴
    customPlot->xAxis->setLabel("时间 (s)");
    customPlot->xAxis->setRange(0, 10); // 10秒数据
    customPlot->xAxis->grid()->setSubGridVisible(true);

    // Y轴
    customPlot->yAxis->setLabel("幅值 (mV)");
    customPlot->yAxis->setRange(-5, 5);
    customPlot->yAxis->grid()->setSubGridVisible(true);

    // 网格样式
    customPlot->xAxis->grid()->setPen(QPen(QColor(200, 200, 200), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setPen(QPen(QColor(200, 200, 200), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(220, 220, 220), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(220, 220, 220), 1, Qt::DotLine));

    // ============ 6. 图例设置 ============
    customPlot->legend->setVisible(true);
    customPlot->legend->setFont(QFont("Arial", 9));
    customPlot->legend->setBrush(QBrush(QColor(255, 255, 255, 200))); // 半透明背景
    customPlot->legend->setBorderPen(QPen(QColor(180, 180, 180), 1));

    // 图例位置
    customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignRight);

    // ============ 7. 十字线初始化 ============
    // 水平线
    crosshairH = new QCPItemStraightLine(customPlot);
    crosshairH->setPen(QPen(QColor(150, 150, 150), 1, Qt::DashLine));
    crosshairH->setVisible(false);

    // 垂直线
    crosshairV = new QCPItemStraightLine(customPlot);
    crosshairV->setPen(QPen(QColor(150, 150, 150), 1, Qt::DashLine));
    crosshairV->setVisible(false);

    // 坐标标签
    coordText = new QCPItemText(customPlot);
    coordText->setPositionAlignment(Qt::AlignLeft|Qt::AlignTop);
    coordText->position->setType(QCPItemPosition::ptAxisRectRatio);
    coordText->position->setCoords(0.02, 0.02); // 左上角
    coordText->setText("X: -, Y: -");
    coordText->setTextAlignment(Qt::AlignLeft);
    coordText->setFont(QFont(font().family(), 9));
    coordText->setPadding(QMargins(5, 5, 5, 5));
    coordText->setBrush(QBrush(QColor(255, 255, 255, 200)));
    coordText->setPen(QPen(QColor(100, 100, 100)));

    // ============ 8. 重绘图表 ============
    customPlot->replot();
}

void MainWindow::setupInteractions()
{
    QCustomPlot *customPlot = ui->widget;

    // 启用鼠标拖拽和缩放
    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    // 鼠标移动事件 - 显示十字线和坐标
    connect(customPlot, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event)
    {
        double x = customPlot->xAxis->pixelToCoord(event->pos().x());
        double y = customPlot->yAxis->pixelToCoord(event->pos().y());

        // 更新坐标显示
        coordText->setText(QString("X: %1 s\nY: %2 mV").arg(x, 0, 'f', 2).arg(y, 0, 'f', 2));

        // 显示十字线
        crosshairV->point1->setCoords(x, customPlot->yAxis->range().lower);
        crosshairV->point2->setCoords(x, customPlot->yAxis->range().upper);
        crosshairH->point1->setCoords(customPlot->xAxis->range().lower, y);
        crosshairH->point2->setCoords(customPlot->xAxis->range().upper, y);

        crosshairV->setVisible(true);
        crosshairH->setVisible(true);

        customPlot->replot();
    });

    // 鼠标离开图表区域时隐藏十字线
    connect(customPlot, &QCustomPlot::mouseRelease, this, [=]()
    {
        crosshairV->setVisible(false);
        crosshairH->setVisible(false);
        customPlot->replot();
    });

    // 旧版兼容的缩放控制
    customPlot->setInteraction(QCP::iRangeZoom, true);  // 启用缩放

    // 实现Ctrl+滚轮缩放 (手动实现)
    customPlot->installEventFilter(this);  // 需要添加eventFilter函数

    // 双击重置视图
    connect(customPlot, &QCustomPlot::mouseDoubleClick, this, [=]()
    {
        customPlot->rescaleAxes();
        customPlot->replot();
    });

    // 右键菜单
    customPlot->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(customPlot, &QCustomPlot::customContextMenuRequested, this, &MainWindow::showContextMenu);
}

void MainWindow::showContextMenu(const QPoint &pos)
{
    QCustomPlot *customPlot = ui->widget;

    QMenu *menu = new QMenu(this);
    menu->setAttribute(Qt::WA_DeleteOnClose);

    // 添加菜单项
    menu->addAction("保存图像", this, [=]()
    {
        QString fileName = QFileDialog::getSaveFileName(this, "保存图像", "", "PNG (*.png);;JPG (*.jpg);;PDF (*.pdf)");
        if (!fileName.isEmpty())
        {
            if (fileName.endsWith(".png"))
                customPlot->savePng(fileName);
            else if (fileName.endsWith(".jpg"))
                customPlot->saveJpg(fileName);
            else if (fileName.endsWith(".pdf"))
                customPlot->savePdf(fileName);
        }
    });

    menu->addSeparator();

    menu->addAction("重置视图", this, [=]()
    {
        customPlot->rescaleAxes();
        customPlot->replot();
    });

    menu->addAction("显示/隐藏图例", this, [=]()
    {
        customPlot->legend->setVisible(!customPlot->legend->visible());
        customPlot->replot();
    });

    menu->popup(customPlot->mapToGlobal(pos));
}

  希望对大家,有所帮助.后续会进行频谱,眼图,瀑布图等的绘画

相关文章:

  • 洛谷 三连击 暴力枚举
  • 如何在 CentOS 7 系统上以容器方式部署 GitLab,使用 ZeroNews 通过互联网访问 GitLab 私有仓库,进行代码版本发布与更新
  • 订单防重复提交与超时取消:AOP + 延迟队列实战
  • Tabnet介绍(Decision Manifolds)和PyTorch TabNet之TabNetRegressor
  • 鼎讯信通 通信安全的终极解决方案:机架式通信干扰机
  • 小白学习java第12天:IO流之缓冲流
  • 数据库守护神-WAL机制
  • 业务幂等性技术架构体系-接口幂等
  • 时序数据异常检测-综述
  • 【蓝桥杯】赛前练习
  • STM32 模块化开发指南 · 第 3 篇 环形缓冲区 RingBuffer 模块设计与单元测试
  • WHAT - React 安全地订阅外部状态源 - useSyncExternalStore
  • 我的Hexo自动Webhook部署方案
  • tree-sitter 的 grammar.js 编写方法
  • 如何进行预算考核
  • Ubuntu22环境下,Docker部署阿里FunASR的gpu版本
  • 【力扣hot100题】(085)单词拆分
  • P8647 [蓝桥杯 2017 省 AB] 分巧克力
  • 智能配电保护:公共建筑安全的新 “防火墙”
  • 大模型评估框架-----OpenCompass模型评估简介
  • 设计师的素材网站/百度seo收费
  • 网站开发任务单百度文库/成人短期技能培训学校
  • 怀化网站排名优化/seo引擎优化外包公司
  • 鞍山网站建设营销/广州新闻24小时爆料热线
  • 响应式网站建设代理/网站关键词排名优化软件
  • 织梦做的网站打不开网页/seo学校