首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QCustomPlot重绘QCPLayer

QCustomPlot重绘QCPLayer
EN

Stack Overflow用户
提问于 2018-03-25 16:03:44
回答 2查看 1.4K关注 0票数 1

我试图弄清楚如何使用QCPLayer只重新绘制图中的某些项目。

qcustomplot 文档声明如下:

如果您经常需要调用一个完整的QCustomPlot::replot,只是因为一个非复杂对象(例如一个项)已经更改,而在图中具有相对静态但复杂的图形,那么可以考虑将定期更改的对象放在自己的层上,并将其模式(QCPLayer::setMode)设置为QCPLayer::lmBuffered。这使得QCustomPlot为该层分配了一个专用的画图缓冲区,并允许使用QCPLayer::replot单独重新绘制它,而不依赖于包含潜在复杂和慢图的其他层。有关详细信息,请参阅相关方法的文档。

这就是我在下面的例子中所要做的:

我正在通过从QCustomPlot继承来创建一个自定义的qcustomplot。

QCustomPlot_custom.h

代码语言:javascript
复制
#pragma once
#include "qcustomplot.h"    
#define USING_LAYER false

struct QCPCursor{
   QCPItemLine *hLine;
   QCPItemLine *vLine;
   QCPItemText* cursorText;
};

class QCustomPlot_custom :
   public QCustomPlot
{
   Q_OBJECT    
private slots:
   void mouseMove(QMouseEvent*);

public:
   QCustomPlot_custom(QWidget* parent = NULL);
   ~QCustomPlot_custom(){}
private:
   QCPLayer* cursorLayer;
   QCPCursor cursor;   
   void manageCursor(double x, double y, QPen pen);
public:
   void init(QVector<double> xdata, QVector<double> ydata);
};

这个类用一些要绘制的数据初始化。它还重载mouseMove事件以控制自定义游标。USING_LAYER设置为true意味着自定义游标被添加到它自己的层(cursorLayer)。

通过将USING_LAYER设置为false,我得到了如下所示的预期效果:

光标由水平和垂直线及坐标显示。

如果我在图中有很多图和/或每个图中的很多点,我将在移动光标时看到一个延迟。(这就是我希望能够通过在一个层中设置光标来重新绘制光标的原因。)

QCustomPlot_custom.cpp

代码语言:javascript
复制
QCustomPlot_custom::QCustomPlot_custom(QWidget* parent)
{
   connect(this, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));   
   QCustomPlot::setInteraction(QCP::iRangeDrag, true);
   QCustomPlot::setInteraction(QCP::iRangeZoom, true);
   if (USING_LAYER){
      this->addLayer("cursorLayer", 0, QCustomPlot::limAbove);
      cursorLayer = new QCPLayer(this, "cursorLayer");
      cursorLayer->setMode(QCPLayer::lmBuffered);
   }
}

void QCustomPlot_custom::init(QVector<double> xdata, QVector<double> ydata)
{   
   this->addGraph();
   this->graph(0)->setData(xdata, ydata);

   QColor colorPen(10, 25, 180, 255);
   QPen pen;
   pen.setWidth(50);
   pen.setColor(colorPen);
   this->graph()->setLineStyle(QCPGraph::lsLine);
   this->graph()->setPen(QPen(colorPen));
   this->xAxis->setLabel("X-axis");
   this->yAxis->setLabel("Y-axis");      
   this->rescaleAxes();
   this->replot();
}

void QCustomPlot_custom::mouseMove(QMouseEvent* event)
{
   //Cursor coordinates:
   double x = this->xAxis->pixelToCoord(event->pos().x());
   double y = this->yAxis->pixelToCoord(event->pos().y());
   manageCursor(x, y, QPen(Qt::DashDotLine));            
   if (USING_LAYER)
      cursorLayer->replot(); 
   else
      this->replot();
}

void QCustomPlot_custom::manageCursor(double x, double y, QPen pen)
{
   if (cursor.hLine)
      this->removeItem(cursor.hLine);
   cursor.hLine = new QCPItemLine(this);   
   cursor.hLine->setPen(pen);
   cursor.hLine->start->setCoords(-QCPRange::maxRange, y);
   cursor.hLine->end->setCoords(QCPRange::maxRange, y);

   if (cursor.vLine)
      this->removeItem(cursor.vLine);
   cursor.vLine = new QCPItemLine(this);   
   cursor.vLine->setPen(pen);
   cursor.vLine->start->setCoords(x, -QCPRange::maxRange);
   cursor.vLine->end->setCoords(x, QCPRange::maxRange);

   //Coordinates as text:   
   if (cursor.cursorText)
      this->removeItem(cursor.cursorText);
   cursor.cursorText = new QCPItemText(this);
   cursor.cursorText->setText(QString("(%1, %2)").arg(x).arg(y));
   cursor.cursorText->position->setCoords(QPointF(x, y));
   QPointF pp = cursor.cursorText->position->pixelPosition() + QPointF(50.0, -15.0);
   cursor.cursorText->position->setPixelPosition(pp);
   cursor.cursorText->setFont(QFont(font().family(), 8));

   //Add to layer:
   if (USING_LAYER){
      cursor.hLine->setLayer(cursorLayer); 
      cursor.vLine->setLayer(cursorLayer); 
      cursor.cursorText->setLayer(cursorLayer);
   }
}

初始化类成员的函数:

代码语言:javascript
复制
void Qt_PlotTest::testPlot(){
   //Create some data and initalize plot:
   QVector<double> yData, xData;
   int imax = 100000;
   for (int i = 0; i < imax; i++){
      double x = double(i) / imax;
      xData.push_back(x);
      yData.push_back(pow(x, 2)*( 1.0 + 0.5*cos(20*x) + 0.1*sin(500*x - 0.1)));
   }
   ui.custom_QWidgetPlot->init(xData, yData);
}

当使用layer方法时,光标不会呈现。我试着理解这些文档,但不清楚如何正确使用QCPLayer

我该怎么做?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-26 13:19:27

正如@EligijusPupeikis提醒我的那样,每当我移动光标时,我都会删除并重新创建光标。

我不认为这会对我的问题产生任何影响,但显然是这样的,因为重新绘制包含新项的图层需要首先重新绘制地块(源:将检查qcustomplot并添加链接)。

所以我的代码现在看起来如下:

代码语言:javascript
复制
QCustomPlot_custom::QCustomPlot_custom(QWidget* parent)
{
   connect(this, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));   
   QCustomPlot::setInteraction(QCP::iRangeDrag, true);
   QCustomPlot::setInteraction(QCP::iRangeZoom, true);
}

void QCustomPlot_custom::init(QVector<double> xdata, QVector<double> ydata)
{   
   this->addGraph();
   this->graph(0)->setData(xdata, ydata);

   QColor colorPen(10, 25, 180, 255);
   QPen pen;
   pen.setWidth(50);
   pen.setColor(colorPen);
   this->graph()->setLineStyle(QCPGraph::lsLine);
   this->graph()->setPen(QPen(colorPen));
   this->xAxis->setLabel("X-axis");
   this->yAxis->setLabel("Y-axis");      
   this->rescaleAxes();
   this->replot();

   if (USING_LAYER){
      this->addLayer("cursorLayer", 0, QCustomPlot::limAbove);
      cursorLayer = this->layer("cursorLayer");
      //cursorLayer = new QCPLayer(this, "cursorLayer");
      cursorLayer->setMode(QCPLayer::lmBuffered);
   }

   //Cursor:
   QPen qpen = QPen(Qt::DashDotLine);
   cursor.hLine = new QCPItemLine(this);
   cursor.hLine->setPen(qpen);
   cursor.vLine = new QCPItemLine(this);
   cursor.vLine->setPen(qpen);
   cursor.cursorText = new QCPItemText(this);
   cursor.cursorText->setFont(QFont(font().family(), 8));

   //Add to layer:
   if (USING_LAYER){
      cursor.hLine->setLayer("cursorLayer");  //"cursorLayer"
      cursor.vLine->setLayer("cursorLayer");
      cursor.cursorText->setLayer("cursorLayer");
   }

}

void QCustomPlot_custom::mouseMove(QMouseEvent* event)
{
   //Cursor coordinates:
   double x = this->xAxis->pixelToCoord(event->pos().x());
   double y = this->yAxis->pixelToCoord(event->pos().y());
   manageCursor(x, y);            
   if (USING_LAYER)
      this->layer("cursorLayer")->replot();
   else
      this->replot();
}

void QCustomPlot_custom::manageCursor(double x, double y)
{
   cursor.hLine->start->setCoords(-QCPRange::maxRange, y);
   cursor.hLine->end->setCoords(QCPRange::maxRange, y);

   cursor.vLine->start->setCoords(x, -QCPRange::maxRange);
   cursor.vLine->end->setCoords(x, QCPRange::maxRange);

   cursor.cursorText->setText(QString("(%1, %2)").arg(x).arg(y));
   cursor.cursorText->position->setCoords(QPointF(x, y));
   QPointF pp = cursor.cursorText->position->pixelPosition() + QPointF(50.0, -15.0);      
 cursor.cursorText->position->setPixelPosition(pp);
}

作为一个测试,如果我绘制了10000点,并将USING_LAYER设置为false,我将注意到移动鼠标时光标上有明显的滞后。当将其设置为true时,将导致光标的平稳移动。

票数 0
EN

Stack Overflow用户

发布于 2018-03-26 07:57:15

加层后

代码语言:javascript
复制
this->addLayer("cursorLayer", 0, QCustomPlot::limAbove);

不要调用QCPLayer构造函数来获取层指针。使用提供的带有层或索引名称的getter:

QCustomPlot::layer ( const QString & name) const

QCustomPlot::layer ( int索引) const

代码语言:javascript
复制
cursorLayer = this->layer("cursorLayer");

另外,每个图和项都被添加到currentLayer中,在您的示例中,不是cursorLayer,而是main。您需要更改当前层。

bool QCustomPlot::setCurrentLayer ( const QString & name)

层)

即:

代码语言:javascript
复制
this->setCurrentLayer("cursorLayer");
this->addGraph();
...
this->setCurrentLayer("main");

或者您可以为每个QCPLayerable指定层。

层)

bool bool层::setLayer( const QString & layerName)

代码语言:javascript
复制
someGraph->setLayer("cursorLayer);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49477877

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档