1. 程式人生 > >qcustomplot滑鼠點選後在座標軸顯示值

qcustomplot滑鼠點選後在座標軸顯示值

首先上圖看下要實現的效果:


即圖中有兩條曲線,滑鼠點選後顯示橫座標的值,以及與兩條曲線交點的縱座標的值。注意:本例只是實現了座標值的顯示,所以顯示的值和曲線值不符,滑鼠點選的事件可以自行實現

參照網址:http://www.qcustomplot.com/index.php/tutorials/specialcases/axistags 的方法,稍加改編實現。

主要步驟:

1.在qt中新增類TagAxis,內容如下

tagaxis.h

#ifndefTAGAXIS_H
#defineTAGAXIS_H
#include<QObject>
#include"qcustomplot.h"
classTagAxis:public
QObject
{
Q_OBJECT
public:
explicitTagAxis(QCPAxis*parentAxis);
virtual~TagAxis();
//setters:
voidsetPen(constQPen&pen);
voidsetBrush(constQBrush&brush);
voidsetTextY1(constQString&text);
voidsetTextY2(constQString&text);
voidsetTextX(constQString&text);
voidupdatePosition(doublevalueY1,double
valueY2,doublevalueX);
signals:
publicslots:
protected:
QCPAxis*mAxis;
intyAxisCount;
QPointer<QCPItemTracer>mDummyTracerY1;
QPointer<QCPItemText>mLabelY1;
QPointer<QCPItemTracer>mDummyTracerY2;
QPointer<QCPItemText>mLabelY2;
QPointer<QCPItemTracer>mDummyTracerX;
QPointer<QCPItemText
>mLabelX;
};
#endif//TAGAXIS_H

tagaxis.cpp

#include"tagaxis.h"
TagAxis::TagAxis(QCPAxis*parentAxis):QObject(parentAxis),
mAxis(parentAxis)
{
mDummyTracerY1=newQCPItemTracer(mAxis->parentPlot());
mDummyTracerY1->setVisible(true);
mDummyTracerY1->position->setTypeX(QCPItemPosition::ptAxisRectRatio);//QCPItemPosition::ptPlotCoords
mDummyTracerY1->position->setTypeY(QCPItemPosition::ptPlotCoords);
mDummyTracerY1->position->setAxisRect(mAxis->axisRect());
mDummyTracerY1->position->setAxes(0,mAxis);
mLabelY1=newQCPItemText(mAxis->parentPlot());
mLabelY1->setLayer("overlay");
mLabelY1->setClipToAxisRect(false);
mLabelY1->setPadding(QMargins(3,0,3,0));
mLabelY1->setBrush(QBrush(Qt::white));
mLabelY1->setPen(QPen(Qt::blue));
mLabelY1->setPositionAlignment(Qt::AlignRight|Qt::AlignVCenter);
mLabelY1->position->setTypeX(QCPItemPosition::ptAxisRectRatio);//QCPItemPosition::ptPlotCoords
mLabelY1->position->setTypeY(QCPItemPosition::ptPlotCoords);
mDummyTracerY2=newQCPItemTracer(mAxis->parentPlot());
mDummyTracerY2->setVisible(true);
mDummyTracerY2->position->setTypeX(QCPItemPosition::ptAxisRectRatio);//QCPItemPosition::ptPlotCoords
mDummyTracerY2->position->setTypeY(QCPItemPosition::ptPlotCoords);
//mDummyTracerY1->position->setAxisRect(mAxis->axisRect());
//mDummyTracerY1->position->setAxes(0,mAxis);
mLabelY2=newQCPItemText(mAxis->parentPlot());
mLabelY2->setLayer("overlay");
mLabelY2->setClipToAxisRect(false);
mLabelY2->setPadding(QMargins(3,0,3,0));
mLabelY2->setBrush(QBrush(Qt::white));
mLabelY2->setPen(QPen(Qt::blue));
mLabelY2->setPositionAlignment(Qt::AlignRight|Qt::AlignVCenter);
mLabelY2->position->setTypeX(QCPItemPosition::ptAxisRectRatio);//QCPItemPosition::ptPlotCoords
mLabelY2->position->setTypeY(QCPItemPosition::ptPlotCoords);
mDummyTracerX=newQCPItemTracer(mAxis->parentPlot());
mDummyTracerX->setVisible(true);
mDummyTracerX->position->setTypeX(QCPItemPosition::ptPlotCoords);//QCPItemPosition::ptPlotCoords
mDummyTracerX->position->setTypeY(QCPItemPosition::ptAxisRectRatio);
//mDummyTracerX->position->setAxisRect(mAxis->axisRect());
//mDummyTracerX->position->setAxes(0,mAxis);
mLabelX=newQCPItemText(mAxis->parentPlot());
mLabelX->setLayer("overlay");
mLabelX->setClipToAxisRect(false);
mLabelX->setPadding(QMargins(3,0,3,0));
mLabelX->setBrush(QBrush(Qt::white));
mLabelX->setPen(QPen(Qt::blue));
mLabelX->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
mLabelX->position->setTypeX(QCPItemPosition::ptPlotCoords);//QCPItemPosition::ptPlotCoords
mLabelX->position->setTypeY(QCPItemPosition::ptAxisRectRatio);
}
TagAxis::~TagAxis()
{
if(mDummyTracerY1)
mDummyTracerY1->parentPlot()->removeItem(mDummyTracerY1);
if(mLabelY1)
mLabelY1->parentPlot()->removeItem(mLabelY1);
if(mDummyTracerY2)
mDummyTracerY2->parentPlot()->removeItem(mDummyTracerY2);
if(mLabelY2)
mLabelY2->parentPlot()->removeItem(mLabelY2);
if(mDummyTracerX)
mDummyTracerX->parentPlot()->removeItem(mDummyTracerX);
if(mLabelX)
mLabelX->parentPlot()->removeItem(mLabelX);
}
voidTagAxis::setPen(constQPen&pen)
{
mLabelY1->setPen(pen);
mLabelY2->setPen(pen);
mLabelX->setPen(pen);
}
voidTagAxis::setBrush(constQBrush&brush)
{
mLabelY1->setBrush(brush);
mLabelY2->setBrush(brush);
mLabelX->setBrush(brush);
}
voidTagAxis::setTextY1(constQString&text)
{
mLabelY1->setText(text);
}
voidTagAxis::setTextY2(constQString&text)
{
mLabelY2->setText(text);
}
voidTagAxis::setTextX(constQString&text)
{
mLabelX->setText(text);
}
voidTagAxis::updatePosition(doublevalueY1,doublevalueY2,doublevalueX)
{
mDummyTracerY1->position->setCoords(0,valueY1);
mLabelY1->position->setCoords(0,valueY1);
mDummyTracerY2->position->setCoords(0,valueY2);
mLabelY2->position->setCoords(0,valueY2);
mDummyTracerX->position->setCoords(valueX,1);
mLabelX->position->setCoords(valueX,1);
}

2.在主檔案中引用

#ifndefMAINWINDOW_H
#defineMAINWINDOW_H
#include<QMainWindow>
#include"qcustomplot.h"
#include"axistag.h"
#include"tagaxis.h"
namespaceUi{
classMainWindow;
}
classMainWindow:publicQMainWindow
{
Q_OBJECT
public:
explicitMainWindow(QWidget*parent=0);
~MainWindow();
privateslots:
voidtimerSlot();
private:
Ui::MainWindow*ui;
QCustomPlot*mPlot;
QPointer<QCPGraph>mGraph1;
QPointer<QCPGraph>mGraph2;
//AxisTag*mTag1;
//AxisTag*mTag2;
TagAxis*tagAxis;
QTimermDataTimer;
};
#endif//MAINWINDOW_H

mainwindow.cpp中實現:

ui->setupUi(this);
mPlot=newQCustomPlot(this);
setCentralWidget(mPlot);
connect(mPlot->yAxis2,SIGNAL(rangeChanged(QCPRange)),mPlot->yAxis,SLOT(setRange(QCPRange)));
connect(mPlot->yAxis2,SIGNAL(rangeChanged(QCPRange)),mPlot->yAxis2,SLOT(setRange(QCPRange)));
mPlot->yAxis2->setVisible(true);
mPlot->addGraph();
mPlot->graph(0)->setPen(QPen(Qt::blue));//linecolorblueforfirstgraph
mPlot->graph(0)->setBrush(QBrush(QColor(0,0,255,20)));//firstgraphwillbefilledwithtranslucentblue
mPlot->addGraph();
mPlot->graph(1)->setPen(QPen(Qt::red));//linecolorredforsecondgraph
tagAxis=newTagAxis(mPlot->graph(0)->valueAxis());
tagAxis->setPen(mPlot->graph(0)->pen());
QVector<double>x(251),y0(251),y1(251);
for(inti=0;i<251;++i)
{
x[i]=i;
y0[i]=qExp(-i/150.0)*qCos(i/10.0);//exponentiallydecayingcosine
y1[i]=qExp(-i/150.0);//exponentialenvelope
}
mPlot->xAxis2->setVisible(true);
mPlot->xAxis2->setTickLabels(false);
mPlot->yAxis2->setVisible(true);
mPlot->yAxis2->setTickLabels(false);
//makeleftandbottomaxesalwaystransfertheirrangestorightandtopaxes:
connect(mPlot->xAxis,SIGNAL(rangeChanged(QCPRange)),mPlot->xAxis2,SLOT(setRange(QCPRange)));
connect(mPlot->yAxis,SIGNAL(rangeChanged(QCPRange)),mPlot->yAxis2,SLOT(setRange(QCPRange)));
//passdatapointstographs:
mPlot->graph(0)->setData(x,y0);
mPlot->graph(1)->setData(x,y1);
//lettherangesscalethemselvessograph0fitsperfectlyinthevisiblearea:
mPlot->graph(0)->rescaleAxes();
//samethingforgraph1,butonlyenlargeranges(incasegraph1issmallerthangraph0):
mPlot->graph(1)->rescaleAxes(true);
//Note:wecouldhavealsojustcalledcustomPlot->rescaleAxes();instead
//Allowusertodragaxisrangeswithmouse,zoomwithmousewheelandselectgraphsbyclicking:
mPlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom|QCP::iSelectPlottables);
tagAxis->setTextY1("-0.3");
tagAxis->setTextY2("0.6");
tagAxis->setTextX("125");
tagAxis->updatePosition(-0.3,0.6,125);
mPlot->replot();

完畢!

完整工程程式碼github地址:https://github.com/cloudsmile/axisTest