QT_QCustomPlot学习
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT_QCustomPlot学习相关的知识,希望对你有一定的参考价值。
QCustomPlot学习
QCustomPlot默认提供了6个层,如下代码所示,分别是:背景层、网格层、主层、坐标轴层、图例层和矩形选择区域层。
1.在一张视图中表现两个线
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
ui->setupUi(this);
demo();
Widget::~Widget()
delete ui;
void Widget::demo()
QVector<double> x,y,z;
for (double i=0;i<10 ;i+=0.1 )
x.append(i);
y.append(i);
z.append(i*i);
ui->cw->addGraph();
ui->cw->graph()->setData(x,y);
ui->cw->addGraph();
ui->cw->graph()->setData(x,z);
ui->cw->graph()->setPen(QPen(QColor(Qt::green)));
ui->cw->graph()->setLineStyle(QCPGraph::LineStyle::lsNone);//设置连线的样式
ui->cw->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCross, 10));//设置散点的样式,ssCross为十字样式
ui->cw->graph()->setSelectable(QCP::SelectionType::stMultipleDataRanges);//设置图形中可选的元素,这里配合选择框使用多点选择,可以通过选取框选择多个点,也可以按住ctrl多选
ui->cw->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables|QCP::iMultiSelect);
ui->cw->replot();
//可以把矩形框设置放在外面
void Widget::on_checkBox_2_clicked(bool checked)
if(checked)
ui->cw->setSelectionRectMode(QCP::SelectionRectMode::srmSelect);//添加鼠标选取矩形框,并设置为选择操作,此时鼠标的拖拽功能失效。按住ctrl可以多选
else
ui->cw->setSelectionRectMode(QCP::SelectionRectMode::srmNone);//取消矩形框选取,鼠标拖拽功能返回
ui->cw->deselectAll();
ui->cw->replot();
2.一张视图中多个图表:使用QCPLayoutGrid
void Widget::demo2()
//一张视图中多个图表
//创建QCPAxisRect
QCPAxisRect* a = new QCPAxisRect (ui->cw);
QCPAxisRect* b = new QCPAxisRect (ui->cw);
//添加到QCPLayoutGrid
ui->cw->plotLayout()->clear();
QCPLayoutGrid* lay = ui->cw->plotLayout() ;
lay->addElement(0,0,a);
lay->addElement(1,0,b);
//创建数据
QVector<QCPGraphData> d1,d2;
for (double i=0;i<10 ;i+=0.1 )
d1.append(QCPGraphData(i,i));
d2.append(QCPGraphData(i,i*i));
//创建数据,添加到QCPGraph
QCPGraph* ga = ui->cw->addGraph(a->axis(QCPAxis::atBottom),a->axis(QCPAxis::atLeft));
ga->data()->set(d1);
ga->rescaleAxes();
QCPGraph* gb = ui->cw->addGraph(b->axis(QCPAxis::atBottom),b->axis(QCPAxis::atLeft));
gb->data()->set(d2);
gb->rescaleAxes();
//同时改变X轴大小,可以用来进行对比
ui->cw->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
connect(ga->keyAxis(),SIGNAL(rangeChanged(QCPRange)),gb->keyAxis(),SLOT(setRange(QCPRange)));
connect(gb->keyAxis(),SIGNAL(rangeChanged(QCPRange)),ga->keyAxis(),SLOT(setRange(QCPRange)));
ui->cw->axisRect(0)->setRangeZoom(Qt::Horizontal);
ui->cw->axisRect(1)->setRangeZoom(Qt::Horizontal);
同步X轴大小:
//同时改变X轴大小,可以用来进行对比
ui->cw->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
for(int i=0 ; i < ui->cw->graphCount(); ++i)
connect(ui->cw->graph(i)->keyAxis(),SIGNAL(rangeChanged(QCPRange)),this,SLOT(setXRange(QCPRange)));
ui->cw->axisRect(i)->setRangeZoom(Qt::Horizontal);
void Widget::setXRange(QCPRange range)
for(int i=0 ; i < ui->cw->graphCount(); ++i)
ui->cw->graph(i)->keyAxis()->setRange(range);
添加checkbox是否同步:
void Widget::on_checkBox_clicked(bool checked)
if(checked)
for(int i=0 ; i < ui->cw->graphCount(); ++i)
connect(ui->cw->graph(i)->keyAxis(),SIGNAL(rangeChanged(QCPRange)),this,SLOT(setXRange(QCPRange)));
ui->cw->axisRect(i)->setRangeZoom(Qt::Horizontal);
ui->cw->axisRect(i)->setRangeDrag(Qt::Horizontal);
ui->cw->graph(i)->rescaleAxes();
else
for(int i=0 ; i < ui->cw->graphCount(); ++i)
disconnect(ui->cw->graph(i)->keyAxis(),SIGNAL(rangeChanged(QCPRange)),this,SLOT(setXRange(QCPRange)));
ui->cw->axisRect(i)->setRangeZoom(Qt::Horizontal|Qt::Vertical);
ui->cw->axisRect(i)->setRangeDrag(Qt::Horizontal|Qt::Vertical);
遗憾的是,现在QCPLayoutGrid这个方法还没找到有QSplitter这样可以分割的部件实现调整窗口的大小。
3.一张视图中多个图表:使用QSplitter
使用两个QCustomPlot窗口,加上一个QSplitter实现调整大小
void Widget::demo3()
ui->cw->plotLayout()->clear();
//创建数据
QVector<QCPGraphData> d1,d2,d3;
for (double i=0;i<10 ;i+=0.1 )
d1.append(QCPGraphData(i,i));
d2.append(QCPGraphData(i,i*i));
d3.append(QCPGraphData(i,qSqrt(i)));
QCustomPlot* qcp1 = new QCustomPlot();
QCustomPlot* qcp2 = new QCustomPlot();
QCustomPlot* qcp3 = new QCustomPlot();
qcp1->addGraph()->data()->set(d1);
qcp2->addGraph()->data()->set(d2);
qcp3->addGraph()->data()->set(d3);
qcp1->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
qcp2->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
qcp3->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
/*QSplitter**/ pSplitter = new QSplitter(Qt::Vertical,this);
pSplitter->addWidget(qcp1);
pSplitter->addWidget(qcp2);
pSplitter->addWidget(qcp3);
ui->show->addWidget(pSplitter); //注意这里的 ui->show为 QGridLayout类型
QCustomPlot* q = nullptr;
for(int i=0;i < pSplitter->count();++i)
q = static_cast<QCustomPlot*>(pSplitter->widget(i));
connect(q->graph()->keyAxis(),SIGNAL(rangeChanged(QCPRange)),this,SLOT(set3Range(QCPRange)));
void Widget::set3Range(QCPRange range)
QCustomPlot* q = nullptr;
for(int i=0;i < pSplitter->count();++i)
q = static_cast<QCustomPlot*>(pSplitter->widget(i));
q->graph()->keyAxis()->setRange(range);
q->replot();
4.时间轴
double now = QDateTime::currentDateTime().toSecsSinceEpoch();
QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
dateTicker->setDateTimeFormat("d MMMM\\n yyyy");
ui->cw->xAxis2->setTicker(dateTicker);
ui->cw->xAxis2->setRange(now,now+24*3600*10);
ui->cw->xAxis2->setVisible(true);
5.实现鼠标左键选框,中键平移,右键菜单
以下鼠标键都在qcustomplot.cpp中修改,注意不要搞错成员函数所在的类名
左键选框:
把官方的框选功能限制在左键上,在函数void QCustomPlot::mousePressEvent(QMouseEvent *event)中修改如下:
void QCustomPlot::mousePressEvent(QMouseEvent *event)
emit mousePress(event);
// save some state to tell in releaseEvent whether it was a click:
mMouseHasMoved = false;
mMousePressPos = event->pos();
//添加 event->button() == Qt::LeftButton ,将选取框按键绑定在左键
if (event->button() == Qt::LeftButton && mSelectionRect && mSelectionRectMode != QCP::srmNone)
if (mSelectionRectMode != QCP::srmZoom || qobject_cast<QCPAxisRect*>(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect
mSelectionRect->startSelection(event);
else if(event->button() != Qt::LeftButton)//添加if
//...
中键平移:
官方默认左键是平移曲线,我们把平移功能改到中键上去,以便右键菜单。直接在函数
void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details)改,把Qt::LeftButton改成Qt::RightButton即可。
void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details)
Q_UNUSED(details)
if (event->buttons() & Qt::midButton)//将Qt::LeftButton改成你要绑定的拖拽的按键
//...
右键菜单:
void demo()
ui->cw->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->cw,&QCustomPlot::customContextMenuRequested,this,&Widget::MenuRequested);
void Widget::MenuRequested(QPoint p)
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addAction("resize",this,[=]()
ui->cw->rescaleAxes();
ui->cw->replot();
);
menu->addAction("zoom",this,[=]()
ui->cw->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
);
menu->addAction("select",this,[=]()
ui->cw->setSelectionRectMode(QCP::SelectionRectMode::srmSelect);
);
menu->addAction("None",this,[=]()
ui->cw->setSelectionRectMode(QCP::SelectionRectMode::srmNone);
);
menu->popup(ui->cw->mapToGlobal(p));//必须要,否则不显示菜单
写进新的类:plotView
//hpp
#include "../../plotLib/qcustomplot.h"
class plotView : public QCustomPlot
public:
plotViewHalcon三 依据点关系计算物体三维位姿Halcon