目录
1 效果图
2 功能描述
3 关键代码
1 实现多坐标系的加入删除,动态更新
2 坐标系X轴同步
3 多坐标系中显示游标
4 添加曲线函数
1 可进行单坐标系多坐标系的切换
2 点击QTableWidget的checkbox可以控制坐标系的数量并显示相应的曲线
3 在多坐标系中显示游标
4 更改曲线的颜色
5 坐标系X轴同步
6 曲线的放大缩小、左右移动、上下移动
头文件里面的部分函数:
public:
int m_WaveIndex;
QCPMarginGroup *marginGroup;
QString currentFileName;
int model;
QVectoraxisList;
SetYValueDialog mSetYValueDialog;
RecFile *pRecGlobal;
bool bCursorMoveShow;
QVector vectorQCPItemText;
QCPAxisRect * rect;
void SetModelState(Model _model);
void UpdataAll();
void ModelSingleCoord();
void ModelXMulY_Coord();
void ModelMulCoord();
void ModelChange(int _model = 0);
void RemoveQCPAxisRectAll();
void SetVisbleQCPAxisRect();
void CreateQCPAxisRect();
void connectAllxAsix(bool on);
void CreateQCPAxisRect(int axis_num);
void UpdataViewTable();
void ClearViewTable();
void ReloadCustomPlot();
void loadFileTXTFile(QString fileName);
void ClearQCPItemText();
void dragEnterEvent(QDragEnterEvent *event) override; //拖入事件
void dropEvent(QDropEvent *event) override; //拖入松开事件
};
void MainWindow::RemoveQCPAxisRectAll()
{
ui->customplot->clearGraphs();
for(int i = 0;i < axisList.count();i++)
{
ui->customplot->plotLayout()->remove(axisList.at(i));
QCPAxisRect * rect = axisList.at(i);
rect = nullptr;
}
axisList.clear();
//此处个人理解删除元素后重新布局
//不执行元素数量不会改变
ui->customplot->plotLayout()->simplify();
qDebug()<customplot->plotLayout()->elementCount();
}
此函数全部删除了QVector
void MainWindow::CreateQCPAxisRect(int axis_num)
{
ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft , marginGroup);
for(int i = 0;i < axis_num;i++){
QCPAxisRect *rect = new QCPAxisRect(ui->customplot);
rect->setMarginGroup(QCP::msLeft , marginGroup);
rect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight);
rect->axis(QCPAxis::atBottom)->setRange(0,2000);
rect->setRangeDrag(Qt::Horizontal | Qt::Vertical); //水平方向拖动
rect->setRangeZoom(Qt::Horizontal | Qt::Vertical); //水平方向缩放
if(i == axis_num - 1)
{
rect->setMargins(QMargins(0, 0, 0, 20));
}
if(!ui->customplot->plotLayout()->hasElement(i+1,0))
ui->customplot->plotLayout()->addElement(i+1,0,rect);
axisList.append(rect);
}
connectAllxAsix(true);
ui->customplot->plotLayout()->simplify();
}
此函数创造多坐标系并加入到边框组marginGroup中,使得Y轴保持一致,由于有默认的坐标系存在,所以这里是i + 1
ui->customplot->plotLayout()->addElement(i+1,0,rect);
void MainWindow::connectAllxAsix(bool on)
{
for (int i = 0; i < axisList.count(); ++i) {
if(on){
connect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
}
else
{
disconnect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
}
for (int j = i+1; j < axisList.count(); ++j) {
if(on)
{
connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
connect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
}
else
{
disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
disconnect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
}
}
}
}
此函数连接信号和槽实现X轴的同步
void MainWindow::mouseMoveEvent( QMouseEvent *event ) {
//return ;
if ( !ui->customplot->viewport().contains( event->pos() ) )
return;
if ( RubBand->isVisible() ) {
QPoint EndPoint = event->pos();
EndPoint.setY(EndPoint.y() + 58);
// EndPoint.setY( ui->customplot->height() );
RubBand->setGeometry( QRect( StartPoint, EndPoint ).normalized() );
}
if(!bCursorMoveShow)
return ;
//获取鼠标坐标,相对父窗体坐标
int x_pos = event->pos().x();
int y_pos = event->pos().y();
double x_val = 0;//ui->customplot->xAxis->pixelToCoord( x_pos );
double y_val = 0;//ui->customplot->yAxis->pixelToCoord( y_pos );
//鼠标坐标转化为CustomPlot内部坐标
for(int i = 0;i < ui->customplot->axisRectCount(); i++)
{
if(event->pos().x() > ui->customplot->axisRects().at(i)->left() && event->pos().y() < ui->customplot->axisRects().at(i)->bottom()\
&&event->pos().x() customplot->axisRects().at(i)->right() && event->pos().y() > ui->customplot->axisRects().at(i)->top())
{
//不要这样转换
// x_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atBottom)->pixelToCoord(x_pos);
// y_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atLeft)->pixelToCoord(y_pos);
tracer->setClipAxisRect(ui->customplot->axisRects().at(i));
tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));
}
}
x_val = ui->customplot->xAxis->pixelToCoord(x_pos);
y_val = ui->customplot->yAxis->pixelToCoord(y_pos);
qDebug()<<"x_val:"< listQCPGraph = ui->customplot->selectedGraphs();
if(listQCPGraph.isEmpty())
{
tracer->setVisible(false);
//bSelectGraph = false;
tracerLabel->setVisible(false);
ui->customplot->replot();
}
else
{
QCPGraph* curGraph = listQCPGraph.at(0);
CDatabind* pUserDat = (CDatabind*)curGraph->userData(0);
double value;
double num = 0;
int index = x_val;
if(pUserDat)
{
int m_nWaveInd = pUserDat->m_nWaveInd;
num = curGraph->data()->at(index)->key;
value = curGraph->data()->at(index)->value;
for(int j = mMoveTime[m_nWaveInd].count() -1; j >= 0;j--)
{
sMoveTime var;
var = mMoveTime[m_nWaveInd].at(j);
if(var.name == "Y*")
{
if(var.num != 0)
{
value = value / var.num;
}
}
else
{
value = value - var.num;
}
}
}
QString mGraphInfo;
mGraphInfo = m_pViewTable->currentItem()->text();
tracer->setVisible(true);
tracerLabel->setVisible(true);
tracer->position->setCoords(x_val, y_val);
tracerLabel->setText( mGraphInfo+"\n( X:"+QString::number(num) +
",Y:"+QString::number(value) + " )" );
pCurLabel[0]->setText("CurX:"+QString::number(num));
pCurLabel[1]->setText("CurY:"+QString::number(value));
ui->customplot->replot();
}
}
重写了mouseMoveEvent函数,其中
tracer->setClipAxisRect(ui->customplot->axisRects().at(i));
tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));
是关键,if(pUserDat)片段中是为了还原曲线放大缩小平移等操作的实际值,可不用理会
void MainWindow::InsertGraph(RecFile *pRec,int nWaveInd){
QCPGraph *graph;
Qt::CheckState bSet;
bSet = m_pViewTable->item(nWaveInd,0)->checkState();
if(!bSet && model == sMulCoord )
graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
ui->customplot->axisRect()->axis(QCPAxis::atLeft));
else if(model == sMulCoord && axisList.at(m_WaveIndex) != nullptr){
graph = ui->customplot->addGraph(axisList.at(m_WaveIndex)->axis(QCPAxis::atBottom),axisList.at(m_WaveIndex )->axis(QCPAxis::atLeft));
m_WaveIndex++;
}
else
graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
ui->customplot->axisRect()->axis(QCPAxis::atLeft));
graph->setVisible(bSet);
graph->setData(pRec->Key,pRec->DatWave[nWaveInd]);
graph->setPen(QPen(QColor::fromHsl((nWaveInd * 30) % 256,255 - (nWaveInd * 30) / 16,128)));
graph->setName(m_pViewTable->item(nWaveInd,0)->text());
CDatabind *m_pUserData = new CDatabind();
m_pUserData->SetUserData(pRec->nFileInd,nWaveInd);
graph->setUserData(0,m_pUserData);
graph->setAdaptiveSampling(true);
}
里面很多变量的定义没有写出来,可根据需要灵活变更。