求大神解答!!关于QCustomplot多坐标轴的QCPItemTracer的游标问题!

月色伤地满霜 2021-01-29 02:47:00
最近在做一个仿真波形的模块,用到了QCustomplot。其中有个功能是模仿matlab的subplot。我的思路是创建多个坐标轴QCPAxisRect,然后往坐标轴添加Graph。最后用QCPItemTracer跟Graph绑定。布局方面就用plotLayout()->addElement()往下添加行。我现在遇到的问题是不管这个游标tracer绑定哪个Graph,他只显示在第0行0列的坐标轴里。其他坐标轴不显示。我不清楚这个新建的QCPAxisRect这个矩形区域能否实现这个显示游标,我也不知道我是不是思路出了问题。求各位大神能够解答!! 下面是测试的代码跟效果图。


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
test();
for ( int i = 0; i < 3; i++) {
tracer[i] = new QCPItemTracer(ui->customPlot);
tracer[i]->setPen(QPen(Qt::DashLine));
tracer[i]->setStyle(QCPItemTracer::tsPlus);//游标样式:十字星、圆圈、方框等

tracerLabel[i] = new QCPItemText(ui->customPlot); //生成游标说明
//下面的代码就是设置游标说明的外观和对齐方式等状态
tracerLabel[i]->setLayer("overlay");
tracerLabel[i]->position->setCoords(0.5, 0);
tracerLabel[i]->setFont(QFont(font().family(), 10));
tracerLabel[i]->setPen(QPen(Qt::black));
tracerLabel[i]->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);
tracerLabel[i]->setBrush(Qt::green);
//下面这个语句很重要,它将游标说明锚固在tracer位置处,实现自动跟随
tracerLabel[i]->position->setParentAnchor(tracer[i]->position);

m_lineV[i] = new QCPItemStraightLine(ui->customPlot);
QPen linesPen(Qt::red, 1, Qt::SolidLine);
m_lineV[i]->setLayer("overlay");
m_lineV[i]->setPen(linesPen);
m_lineV[i]->setClipToAxisRect(true);
m_lineV[i]->point1->setCoords(0, 0);
m_lineV[i]->point2->setCoords(0, 0);
}
connect(ui->customPlot, &QCustomPlot::mouseMove, this, &MainWindow::myMoveEvent);
}

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

void MainWindow::myMoveEvent(QMouseEvent *event)
{
double xValue;
double yValue;

qDebug() << "aaaa";
double yy = wideAxisRect->axis(QCPAxis::atBottom)->pixelToCoord(event->pos().x());
m_lineV[0]->point1->setCoords(yy, 1);
m_lineV[0]->point2->setCoords(yy, 0);
tracer[0]->setGraph(mainGraphCos);//将游标和该曲线图层想连接
tracer[0]->position->setAxes(wideAxisRect->axis(QCPAxis::atBottom), wideAxisRect->axis(QCPAxis::atLeft));
tracer[0]->setGraphKey(yy); //将游标横坐标(key)设置成刚获得的横坐标数据
tracer[0]->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得(这就不用手动去计算了)
tracer[0]->updatePosition(); //使得刚设置游标的横纵坐标位置生效
//以下代码用于更新游标说明的内容
xValue = tracer[0]->position->key();
yValue = tracer[0]->position->value();
//设置游标说明(tracerLabel)的内容
tracerLabel[0]->setText(QString("x = %1, y = %2").arg(xValue).arg(yValue));

double xx = subRectLeft->axis(QCPAxis::atBottom)->pixelToCoord(event->pos().x());
m_lineV[1]->point1->setCoords(xx, 1);
m_lineV[1]->point2->setCoords(xx, 0);
tracer[1]->setGraph(subGraphRandom);//将游标和该曲线图层想连接
tracer[1]->position->setAxes(subRectLeft->axis(QCPAxis::atBottom), subRectLeft->axis(QCPAxis::atLeft));
tracer[1]->setGraphKey(xx); //将游标横坐标(key)设置成刚获得的横坐标数据x
tracer[1]->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得(这就不用手动去计算了)
tracer[1]->updatePosition(); //使得刚设置游标的横纵坐标位置生效
//以下代码用于更新游标说明的内容
xValue = tracer[1]->position->key();
yValue = tracer[1]->position->value();
//设置游标说明(tracerLabel)的内容
tracerLabel[1]->setText(QString("x = %1, y = %2").arg(xValue).arg(yValue));


double x = subRectRight->axis(QCPAxis::atBottom)->pixelToCoord(event->pos().x());
m_lineV[2]->point1->setCoords(x, 1);
m_lineV[2]->point2->setCoords(x, 0);
tracer[2]->setGraph(subBars);//将游标和该曲线图层想连接
tracer[2]->position->setAxes(subRectRight->axis(QCPAxis::atBottom), subRectRight->axis(QCPAxis::atLeft));
tracer[2]->setGraphKey(x); //将游标横坐标(key)设置成刚获得的横坐标数据x
tracer[2]->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得(这就不用手动去计算了)
tracer[2]->updatePosition(); //使得刚设置游标的横纵坐标位置生效
//以下代码用于更新游标说明的内容
xValue = tracer[2]->position->key();
yValue = tracer[2]->position->value();
//设置游标说明(tracerLabel)的内容
tracerLabel[2]->setText(QString("x = %1, y = %2").arg(xValue).arg(yValue));

ui->customPlot->replot();
}

void MainWindow::test()
{
ui->customPlot->plotLayout()->clear(); // 首先清空默认的轴矩形,让我们从头开始

ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables | QCP::iSelectLegend);
wideAxisRect = new QCPAxisRect(ui->customPlot); // 还记得setupDefaultAxes为true时的作用吗,忘了的话翻上去看吧
wideAxisRect->setupFullAxesBox(true); // 让四个轴关联,并全部显示出来
wideAxisRect->addAxis(QCPAxis::atLeft)->setTickLabelColor(QColor("#6050F8")); // 在左边多添加一个轴并且设置它的颜色


ui->customPlot->plotLayout()->addElement(2, 0, wideAxisRect); // 在第一行添加轴矩形 // 在第二行添加一个子布局,后面会添加两个轴矩形在里面

subRectLeft = new QCPAxisRect(ui->customPlot); // 不配置轴
subRectRight = new QCPAxisRect(ui->customPlot);


ui->customPlot->plotLayout()->addElement(0, 0, subRectLeft); // 在第一列添加轴矩形
ui->customPlot->plotLayout()->addElement(1, 0, subRectRight); // 在第二列添加轴矩形


subRectLeft->axis(QCPAxis::atLeft)->ticker()->setTickCount(2); // 设置轴的刻度为一个固定的步进值
subRectRight->axis(QCPAxis::atLeft)->ticker()->setTickCount(2);


// 准备数据
QVector<QCPGraphData> dataCos(21), dataGauss(50), dataRandom(100);
QVector<double> x3, y3;
qsrand(3);
for (int i=0; i<dataCos.size(); ++i) {
dataCos[i].key = i/(double)(dataCos.size()-1)*10-5.0;
dataCos[i].value = qCos(dataCos[i].key);
}
for (int i=0; i<dataGauss.size(); ++i) {
dataGauss[i].key = i/(double)dataGauss.size()*10-5.0;
dataGauss[i].value = qExp(-dataGauss[i].key*dataGauss[i].key*0.2)*1000;
}
for (int i=0; i<dataRandom.size(); ++i) {
dataRandom[i].key = i/(double)dataRandom.size()*10;
dataRandom[i].value = qrand()/(double)RAND_MAX-0.5+dataRandom[qMax(0, i-1)].value;
}
x3 << 1 << 2 << 3 << 4;
y3 << 2 << 2.5 << 4 << 1.5;

// mainGraphCos和 mainGraphGauss 共享下轴,但是它们的左轴不同
mainGraphCos = ui->customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), wideAxisRect->axis(QCPAxis::atLeft));
mainGraphCos->data()->set(dataCos);
mainGraphCos->valueAxis()->setRange(-1, 1);
mainGraphCos->rescaleKeyAxis();
mainGraphCos->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::black), QBrush(Qt::white), 6));
mainGraphCos->setPen(QPen(QColor(120, 120, 120), 2));


subGraphRandom = ui->customPlot->addGraph(subRectLeft->axis(QCPAxis::atBottom), subRectLeft->axis(QCPAxis::atLeft));
subGraphRandom->data()->set(dataCos);
subGraphRandom->valueAxis()->setRange(-1,5);


subBars = ui->customPlot->addGraph(subRectRight->axis(QCPAxis::atBottom), subRectRight->axis(QCPAxis::atLeft));
subBars->data()->set(dataGauss);
subBars->valueAxis()->setRange(0,1000);

qDebug() << ui->customPlot->axisRectCount();
qDebug() << ui->customPlot->graphCount();
QCPMarginGroup *marginGroup = new QCPMarginGroup(ui->customPlot);

for (int j = 0; j < ui->customPlot->axisRectCount(); j++) {
ui->customPlot->axisRect(j)->setMarginGroup(QCP::msLeft|QCP::msRight, marginGroup);
}
}

...全文
4128 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
bjtn 2023-05-15
  • 打赏
  • 举报
回复

你好,我的参考线在哪个坐标系都不显示啊

Jana_Wang 2021-06-11
  • 打赏
  • 举报
回复

解决了吗?我也有这个问题,求解答,谢谢

Gavin0911 2021-07-20
  • 举报
回复 6
@Jana_Wang 用setClipAxisRect 来指定坐标轴
xiangpp2022 2023-12-02
  • 举报
回复
@Gavin0911 感谢,解决了我的问题

65,171

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧