[英]QCustomPlot replot QCPLayer
我试图弄清楚如何使用QCPLayer重新绘制图中的某些项目。
qcustomplot 文档指出:
如果仅由于非复杂对象(例如某项)在图中具有相对静态但复杂的图形而发生变化时,才经常需要调用完整的QCustomPlot :: replot,请考虑将定期变化的对象放置在自己的图层上并对其进行设置模式(QCPLayer :: setMode)转换为QCPLayer :: lmBuffered。 这使QCustomPlot为该层分配了专用的绘制缓冲区,并允许使用QCPLayer :: replot对其进行单独重新绘制,而与包含潜在复杂图和慢图的其他层无关。 有关详细信息,请参见相应方法的文档。
在下面的示例中,我试图这样做:
我正在通过从QCustomPlot
继承来创建自定义 QCustomPlot
:
QCustomPlot_custom.h
#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
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);
}
}
初始化类成员的函数:
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
尚不清楚。
我应该怎么做?
添加图层后
this->addLayer("cursorLayer", 0, QCustomPlot::limAbove);
不要调用QCPLayer
构造函数来获取层指针。 将提供的吸气剂与层或索引的名称一起使用:
QCPLayer * QCustomPlot :: layer(const QString&name)const
QCPLayer * QCustomPlot :: layer(int index)常量
cursorLayer = this->layer("cursorLayer");
同样,每个Graph和Item都添加到currentLayer中,在您的情况下,它不是cursorLayer
而是main
。 您需要更改当前图层
bool QCustomPlot :: setCurrentLayer(const QString&name)
bool QCustomPlot :: setCurrentLayer(QCPLayer *层)
即:
this->setCurrentLayer("cursorLayer");
this->addGraph();
...
this->setCurrentLayer("main");
或者,您可以为每个QCPLayerable
指定图层
布尔QCPLayerable :: setLayer(QCPLayer *层)
布尔QCPLayerable :: setLayer(const QString&layerName)
someGraph->setLayer("cursorLayer);
正如@EligijusPupeikis提醒我的那样,每次移动光标时,我都会删除并重新创建光标。
我认为这不会对我的问题产生任何影响,但是显然是这样,因为重新部署其中包含新项目的图层需要先重新部署图( 来源:将检查qcustomplot doc并添加link )。
所以我的代码现在看起来像这样:
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);
}
作为测试,如果我绘制10 000 000点,并将USING_LAYER
设置为false
,则在移动鼠标时,我会注意到光标上的明显滞后。 将其设置为true
,将使光标平滑移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.