最近在做一個仿真波形的模塊,用到了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);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/254128.html
標籤:C++ 語言
