Qt 使用 qcustomplot 绘制曲线例子
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 使用 qcustomplot 绘制曲线例子相关的知识,希望对你有一定的参考价值。
参考技术A 源文件#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "cwidgetcheckbox.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui->setupUi(this);
m_pPlot = new QCustomPlot;
m_pPlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iMultiSelect|QCP::iSelectOther|QCP::iSelectItems);
m_pPlot->axisRect()->setupFullAxesBox();
m_pPlot->xAxis->setLabel("时间");
m_pPlot->yAxis->setLabel("值");
m_pPlot->xAxis->setRange(0,30);
m_pPlot->yAxis->setRange(0,100);
m_pPlot->legend->setVisible(true);
//m_pPlot->graph( index )->setName(QString::fromStdString(nameVec[0][0]));
ui->verticalLayout->addWidget( m_pPlot );
m_id = startTimer(10);
m_line = m_pPlot->addGraph();
m_line->setName( tr("test") );
m_line->setPen(QPen(QColor(255,0,0)));
m_line->setScatterStyle(QCPScatterStyle::ssDisc);
m_index = 0;
MainWindow::~MainWindow()
delete ui;
double MainWindow::getData(double time)
double s = qCos( time * M_PI * 2 ) ;
return s;
void MainWindow::timerEvent(QTimerEvent *event)
int data = qrand()%20;
m_line->addData(m_index, data);
//m_line->addData(vecX,m_vetData);
m_pPlot->replot();
m_index++;
if( m_index > 31 )
m_pPlot->xAxis->setRange(m_index-30,m_index);
QMainWindow::timerEvent(event);
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qcustomplot.h"
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
double getData(double time);
protected:
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
//void timerEvent(QTimerEvent *event);
private slots:
private:
Ui::MainWindow *ui;
QCPGraph * m_line;
QCustomPlot * m_pPlot;
QVector m_vetData;
int m_index;
int m_id;
;
#endif // MAINWINDOW_H
Qt QCustomPlot 点状网格线实现和曲线坐标点拾取
Qt QCustomPlot 点状网格线实现和曲线坐标点拾取
文章目录
关键字:
QCustomPlot
、
grid
、
Qt
、
拾取
、
背景
摘要
今天被封控在家,但是万恶的资本家是不会让我在家摸鱼的,所以还是给了需求来,所以还是得搞。今天要接着研究QCustomPlot
,老实说,这个也是我第一次用,也没有系统的研究过,只是用到了啥现研究,难免哪里问题或者不合理甚至是理解错误的地方。欢迎大家评论区交流。
我想实现的效果
有两个点,第一个是那个类似星星的背景点阵,我暂时先这么称呼它,因为我也不知道专业名称叫啥;第二个就是这个游标了,就是可以精确显示曲线上每个点的信息,其实就是坐标,如下图所示。这里应为我的需求只需要显示对应的值,所以我就吧X轴的数据隐藏掉了。
点阵的实现
先来解决第一个点阵的问题,这个其实是最耗时的,因为网上没有现成的代码,没得抄(应该是叫莫得参考)。只能自己慢慢摸索。
第一版本,使用QPen Style
我发现 QCustomPlot
坐标轴和网格有一个接口就是设置QPen
,所以打算通过设置坐标轴的网格的画笔来实现这个效果。在看帮助文档里面有一个样式是Qt::DotLine
,如下图所示,是不是就可以实现点了。
结果就是发现我还是太淡出了,如果真的可以这么简单,那就好了。
到时很简单,就是两行代码,如下
gCustomplot->yAxis->grid()->setPen(QPen(QColor(188,188,188,188),1,Qt::DotLine));
gCustomplot->yAxis->grid()->setZeroLinePen(QPen(QColor(188,188,188,188),1,Qt::DotLine));
效果确实差强人意,如下图所示,这密密麻麻的虚线,咋也不想那种心电图上看到的样子,所以还是失败。
第二版本,通过设置背景
其实就是我发现在设置背景时候,可以通过画刷QBursh
来实现背景填充,而我又碰巧发下QBrush
中有一个Qt::Dense7Pattern
填充很可能可以使用,如下图所示。所以,这个一度让我以为可以解决这个问题,甚至主动报告领导缩短了时间(这个时候其实脑子已经进水了)。
要么说听话要听后半截呢,所以还是有看我后面的但是。但是呢,效果确实更为渣渣,如下图所示。
其实看到这个效果的时候,我就觉得我今晚是要和我的小椅子摩擦摩擦一晚上了,真实麻烦他们给麻烦开门,麻烦到家了,为啥要和领导说可以今天搞定的,真实,阿西。
第三版本,回到QPen Style
就在我一筹莫展,瞎扒拉Qt 帮助文档的时候,发现了一个神奇的东西。Qt::CustomDashLine
这个翻译一下不就是自定义虚线
吗。哎嗨嗨,如果使用这个自定义虚线结合第一版的网格,是不是就可以试下了。
要么说这帮助文档还得属Qt 了,连怎么用都给你了,如下所示。
大致就是先定义个容器,这个容器就是用来存放你自定义虚线的参数的,和面又定义了space的变量,这个看字面意思也就是间隔,空格的意思,那肯定就是空白部分了。再就是把你要显示的长度个间隔按照你的需求,存入到这个容器中。完了通过一个叫setDashPattern()
接口放到你的画笔中,就可以绘制自己定义的曲线了。这人家都给说的这么明白了,咱要是再不试一试,那岂不是对不起这文档了。所以撸起代码了,先看下核心代码
QPen gridPen; /// 自定义一个画笔
gridPen.setColor(QColor(188,188,188,188)); /// 设置画笔颜色
QVector<qreal> myDothline; /// 定义一个容器,用来存放自定义曲线的内容数据
qreal space = 25; /// 定义曲线间隔
myDothline << 0.2 << space; /// 将自定义曲线数据装入数组
gridPen.setDashPattern(myDothline); /// 将自定义的曲线装在到自定义的画笔中
gridPen.setWidth(3); /// 设置线宽
gridPen.setCapStyle(Qt::RoundCap);
gridPen.setJoinStyle(Qt::RoundJoin);
gCustomplot->yAxis->setBasePen(QPen(QColor(0,0,0,0)));// 设置Y轴基础颜色
gCustomplot->yAxis->setTickLabels(false); // 设置不显示刻度值
gCustomplot->yAxis->setSubTicks(false); // 设置不显示子刻度线
gCustomplot->yAxis->setTicks(false); // 设置不显示刻度线
gCustomplot->yAxis->grid()->setPen(gridPen); // 设置线样式
gCustomplot->yAxis->grid()->setZeroLinePen(gridPen); // 设置0刻线样式
效果就出来了,如下
这里需要注意两个参数,就是线宽和这个自定义曲线的长度,即myDothline << 0.2 << space;
中的0.2
和gridPen.setWidth(3)
中的3
这两需要大家不断修改和测试,我开始出来的都是横短线,慢慢修改这两个参数,最终出现了这种看着基本就是小圆点的效果。
所以到这里,基本就完成了我这个点阵背景的需求了。希望对小伙伴你也有一定帮助。
取曲线上的点
这个有的抄,基本调试一下就可以使用。这里就直接上代码(这个也是我抄来的,稍微加入了一点点自己的逻辑)
void XXXXXXXXXXXX::slot_showTracer(bool isShow)
mflagIsShowTracer = isShow;
if(mflagIsShowTracer)
if(!tracer)
tracer = new QCPItemTracer(gCustomplot); // 生成游标
tracer->setPen(QPen(Qt::white)); // 圆圈轮廓颜色
tracer->setBrush(QBrush(Qt::white)); // 圆圈圈内颜色
tracer->setStyle(QCPItemTracer::tsCircle); // 圆圈
tracer->setSize(5); // 设置大小
tracer->setVisible(false); // 需要线隐藏,不然不然会触发默认现实Bug
if(!tracerLabel)
tracerLabel = new QCPItemText(gCustomplot); // 生成游标说明
tracerLabel->setText("");
tracerLabel->setLayer("overlay"); // 设置图层为overlay,因为需要频繁刷新
// tracerLabel->setPen(QPen(Qt::green)); // 设置游标说明颜色
tracerLabel->setColor(QColor(255,0,255));
tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); // 左上
tracerLabel->position->setParentAnchor(tracer->position); // 将游标说明锚固在tracer位置处,实现自动跟随
tracerLabel->setVisible(false); // 需要线隐藏,不然不然会触发默认现实Bug
else
tracer->setVisible(false);
tracerLabel->setVisible(false);
鼠标移动槽函数,这里其实也可以不这么写,可以直接重写QCustomplot的鼠标移动函数。
void XXXXXXXXXXXX::slot_mouseMove(QMouseEvent *e)
if(mflagIsShowTracer)
tracer->setVisible(true);
tracerLabel->setVisible(true);
double x = gCustomplot->xAxis->pixelToCoord(e->pos().x()); // 获得鼠标位置处对应的横坐标数据x
tracer->setGraph(gCustomplot->graph(0)); // 将游标和该曲线图层想连接
tracer->setGraphKey(x); // 将游标横坐标设置成刚获得的横坐标数据x
tracer->setInterpolating(false); // 游标的纵坐标可以通过曲线数据线性插值自动获得
tracer->updatePosition(); // 使得刚设置游标的横纵坐标位置生效
//更新游标说明的内容
// double xValue = tracer->position->key();
double yValue = tracer->position->value();
tracerLabel->setText(QString("%1 μV").arg(yValue));
gCustomplot->replot(); // 重绘
这样写成槽函数的话,需要在代码中再关联一下槽函数,这样就实现了拾取点了。
connect(gCustomplot,&QCustomPlot::mouseMove,this,&Turing_Monitor_Kernel::slot_mouseMove);
以上是关于Qt 使用 qcustomplot 绘制曲线例子的主要内容,如果未能解决你的问题,请参考以下文章
Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)
Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)