PDA

View Full Version : Curve tracking example is very slowly



kuzulis
13th November 2016, 15:05
Hi all.

I have faced with the problem of very slow movements of "rubber band" lines when more than 3-curves are attached.
I have implemented the code from the "qwt-6.1.3\playground\curvetracker\" example:



struct compareX
{
inline bool operator()(const double x, const QPointF &pos) const
{
return (x < pos.x());
}
};

CurveTracker::CurveTracker(QWidget *canvas)
: QwtPlotPicker(canvas)
{
}

QRect CurveTracker::trackerRect(const QFont &font) const
{
QRect r = QwtPlotPicker::trackerRect(font);
// Always show the info on left-top of window.
r.moveTo(0, 0);
return r;
}

QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
// Inverse iterations over all attached curves.
QString info;
const auto curves = plot()->itemList(QwtPlotItem::Rtti_PlotCurve);
for (auto curveIt = curves.crbegin(); curveIt != curves.crend(); ++curveIt) {

// Show info only for visible curves.
if (!(*curveIt)->isVisible())
continue;

const QString curveInfo = curveInfoAt(static_cast<const QwtPlotCurve *>(*curveIt), pos);
if (!curveInfo.isEmpty()) {
if (!info.isEmpty())
info += tr("<br>");
info += curveInfo;
}
}
return info;
}

QString CurveTracker::curveInfoAt(const QwtPlotCurve *qwtcurve, const QPointF &pos) const
{
const QLineF line = curveLineAt(qwtcurve, pos.x());
if (line.isNull())
return QString();

const double y = line.pointAt((pos.x() - line.p1().x()) / line.dx()).y();
QString info(tr("<font color=""%1"">%2</font>"));
return info.arg(qwtcurve->pen().color().name()).arg(y);
}

QLineF CurveTracker::curveLineAt(const QwtPlotCurve *qwtcurve, double x) const
{
QLineF line;
const auto samplesCount = qwtcurve->dataSize();
if (samplesCount >= 2) {
const QRectF boundingRect = qwtcurve->boundingRect();
if ((boundingRect.width() > 0)
&& (x >= boundingRect.left())
&& (x <= boundingRect.right())) {

auto lessfunc = [](const double x, const QPointF &pos) { return (x < pos.x()); };
int sampleIndex = qwtUpperSampleIndex<QPointF>(*qwtcurve->data(), x, lessfunc);

if (sampleIndex == -1) {
const auto lastSample = qwtcurve->sample(samplesCount - 1);
if (x == lastSample.x())
sampleIndex = samplesCount - 1;
}
if (sampleIndex > 0) {
line.setP1(qwtcurve->sample(sampleIndex - 1));
line.setP2(qwtcurve->sample(sampleIndex));
}
}
}
return line;
}


And I see that if I use 3 and more curves, then the rubber band's crosshair isn't in time behind movements of the
mouse cursor, it lags behind on speed. And with the 15-curves or more, the delay of a sight is stronger.

I see this delay even with "pure" QwtPlotPicker...

So, is any tricks to solve it?

PS: Qwt6.3-multiaxes, Qt 5.7, MSVC2015x86.

BR,
Denis

Added after 13 minutes:

I found, that even this code brings to lags:



QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
QString info;
for (int i = 0; i < 15; ++i) {
info += tr("<br>");
info += QString::number(qrand() % 1000);
}
return info;
}


Added after 11 minutes:

UPD: Seems, that source of issue in HTML tags:



QString info(tr("<font color=""%1"">%2</font>"));


So... seems, we need to avoid to use the trackerTextF() method.

Seems, we need to draw the tracker's rect with all contents manually, directly in QwtPicker::drawTracker.. :(

Or, I am mistaken ?

Uwe
13th November 2016, 17:42
Using rich text is slow and there is nothing you can do about it, but it is not that slow to explain the effects you describe.
The only obvious thing I can see in your code is, that you are running the text through tr ( what doesn't make any sense to me ) - maybe it does something in your context.

I increased the curvetracker example to 10 curves and I can't see any difference.


insertCurve( "Curve 3", Qt::darkCyan, points2 );
insertCurve( "Curve 4", Qt::darkYellow, points2 );
insertCurve( "Curve 5", Qt::darkRed, points2 );
insertCurve( "Curve 6", Qt::darkRed, points2 );
insertCurve( "Curve 7", Qt::darkRed, points2 );
insertCurve( "Curve 8", Qt::darkRed, points2 );
insertCurve( "Curve 9", Qt::darkRed, points2 );
insertCurve( "Curve 1o", Qt::darkRed, points2 );


Are you running on a slow piece of hardware - like the raspi ?
Did you build Qt in debug mode ?
Anything else what explains, why you are that much slower than my desktop system ( Linux, OpenSuse 12.2, bogomips : 4988.86 )



Uwe

kuzulis
13th November 2016, 19:00
Hi Uwe,

thanks for your answer.

Now I too use the curvetracker with this simplification:



Plot::Plot( QWidget *parent ):
QwtPlot( parent)
{
// curves
for (int i = 0; i < 15; ++i) {
QPolygonF points(2000);
for (int p = 0; p < 2000; ++p) {
points.append({ double(p), double(qrand() % 100) });
}

insertCurve( tr("Curve %1").arg(i), qrand() % 255, points );
}

CurveTracker* tracker = new CurveTracker( this->canvas() );

// for the demo we want the tracker to be active without
// having to click on the canvas
tracker->setStateMachine( new QwtPickerTrackerMachine() );
tracker->setRubberBandPen( QPen( "MediumOrchid" ) );
}

void Plot::insertCurve( const QString &title,
const QColor &color, const QPolygonF &points )
{
QwtPlotCurve *curve = new QwtPlotCurve();
curve->setTitle( title );
curve->setPen(color),
curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
curve->setSamples( points );
curve->attach( this );
}


and I got same result. When I expand the plot to the whole Display width, I got lags of a crosshair from the mouse position (this depends on mouse moving speed).


Are you running on a slow piece of hardware - like the raspi ?

No, I use the Desktop PC with Windows 10 (64bit) + Qwt 6.3 (yes? multiaxes) + Qt 5.7.0 + MSVC2015x86


Did you build Qt in debug mode ?

Yes, in debug mode.


Anything else what explains, why you are that much slower than my desktop system ( Linux, OpenSuse 12.2, bogomips : 4988.86 )

I have Desktop i5-3470@3.2GHzx8GB RAM .

Uwe
13th November 2016, 19:18
Yes, in debug mode.
When Qt has been built in debug mode lots of assertions and extra tests are compiled in. AFAIR this has a significant slow down effect on text rendering.
So the first thing I would do is to try a release version.

Uwe

kuzulis
13th November 2016, 19:44
Yes, you are right. Using the Release mode improves the performance.
But, anyway, If I move the mouse quickly, then crosshair lags behind, but to a lesser extent.
But, OK, many thanks, it is enougth for me. :)