求大神解答!!关于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);
}
}

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

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

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

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

Gavin0911 2021-07-20
  • 举报
回复 7
@Jana_Wang 用setClipAxisRect 来指定坐标轴
xiangpp2022 2023-12-02
  • 举报
回复
@Gavin0911 感谢,解决了我的问题
内容概要:本文档系统整合了基于MATLAB/Simulink的风力涡轮机雷达信号仿真、电力系统优化、新能源调控及多领域智能算法应用资源,涵盖风电功率平抑、混合储能协同调频、综合能源系统调度、无人机三维路径规划、电动汽车参与调度、电氢氨耦合系统优化等前沿科研方向。资源包提供大量可复现的Matlab代码、Simulink仿真模型、数据集及配套论文,涉及GWO、PSO、WOA、HHO等多种智能优化算法,以及LSTM、CNN、GRU等深度学习模型在负荷预测、故障诊断、信号处理中的应用,尤其聚焦于风电与雷达信号交互、储能功率分配、虚拟电厂运行、微电网多时间尺度优化等关键技术的仿真实现。; 适合人群:具备一定MATLAB编程基础,从事电力系统、新能源、智能优化、信号处理、雷达仿真、综合能源管理等相关领域的科研人员及研究生;工作1-3年相关方向的工程师。; 使用场景及目标:①开展风力发电系统与雷达信号交互仿真研究;②复现高水平期刊论文中的优化调度、故障诊断、功率预测模型;③进行无人机路径规划、储能系统设计、综合能源系统优化等课题研究与论文撰写;④借助成熟的代码框架快速搭建仿真模型,提升科研效率与工程实践能力。; 阅读建议:建议按主题分类浏览资源列表,优先选择标注“复现”“顶刊”“EI”等高价值项目,结合提供的网盘链接下载完整代码与数据,配合Simulink仿真模型与说明文档进行调试与二次开发,注重算法实现与实际工程问题的深度融合。
日常处理文本内容时,你是否也常常被这些琐碎又烦人的操作消耗大量时间:从网页复制来的文章满是空行和多余空格,要一段段手动清理;从不同渠道收集的文档繁简混杂,格式五花八门,想统一规范却只能逐篇调整;面对数千行的数据,想按行排序、去重、添加行号,却找不到一个趁手的小工具;更别提Base64编解码、URL转义这些开发中高频使用的操作,每次都得打开在线网站反复折腾——这些看似零散的文本处理需,单独去搜工具费时费力,用Word又杀鸡用牛刀,始终缺少一款能把这些功能聚合在一起、打开即用的桌面工具。而 大飞哥软件自习室——文本批量整理工具 v2.0正是为整合这些高频文本处理需而生的专业效率工具,它集文件管理、文本清洗、格式转换、查找替换、批量插入、排序打乱、编码解码、实时统计等近三十项实用功能于一身,采用多标签页设计支持同时编辑多个文档,所有操作均支持撤销与重做,让你在写代码、整理素材、编辑文案时再也不用东拼西凑找工具,一个软件搞定全部文本处理需。 软件的核心功能模块围绕文本处理的完整工作流展开,覆盖了从“粗加工”到“精处理”的各个环节。文本清洗模块提供了行首尾去空格、清除所有空格、删除空行、合并多余空格、去除重复行、清除HTML标签等六项功能,一键将脏乱差的原始文本快速规整为干净可用的素材。文本转换模块则涵盖了繁简互转、标点中英文互转、全半角互转、全部大写/小写/首字母大写等选项,尤其适合需要批量处理多语言或不同格式规范的文本内容。查找替换模块不仅支持普通文本替换,更提供了正则表达式和区分大小写选项,查找、替换、全部替换、选区替换四种模式灵活应对不同场景。批量插入文本模块更是独树一帜——用户可预设两组插入内容,选择插入到当前段首/段尾或所有段首/段尾,四个单选按钮搭配两个输入框,实现八种插入组合,为批量处理结构化文本提供了极大的便利。

65,210

社区成员

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

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