PDA

View Full Version : Selecting QwtPlotCurve from QwtPlot



Christoss
24th June 2013, 13:59
Hello there,
I want to have a window that contains a QTable and a QwtPlot and when I select a curve with the mouse, the points of the curve will appear at the QTable.
The problem that I have is that I don't know how to select a curve. I have seen the example (event_filter) that just selects points not the whole curve.
Do you have any suggestions?
Thank you in advance

Nicho
24th June 2013, 15:36
this may be a way: you can use a point picker or subclass it to get the current mouse position, and code a function to judge whether the position is on one of the segments of one of the curves.

jesse_mark
24th June 2013, 15:59
the Even_filter example is all what you need,
in this example it does select the curve, in the select method,

in these lines:




for ( QwtPlotItemIterator it = itmList.begin();
it != itmList.end(); ++it )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve *c = static_cast<QwtPlotCurve *>( *it ); /// c is the curve you clicked on

double d;
int idx = c->closestPoint( pos, &d );
if ( d < dist )
{
curve = c;
index = idx;
dist = d;
}
}

Christoss
24th June 2013, 17:27
this may be a way: you can use a point picker or subclass it to get the current mouse position, and code a function to judge whether the position is on one of the segments of one of the curves.

Yes this is my my question, how to get the segments of the curve, in order to check them with mouse position


the Even_filter example is all what you need,
in this example it does select the curve, in the select method,

in these lines:




for ( QwtPlotItemIterator it = itmList.begin();
it != itmList.end(); ++it )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve *c = static_cast<QwtPlotCurve *>( *it ); /// c is the curve you clicked on

double d;
int idx = c->closestPoint( pos, &d );
if ( d < dist )
{
curve = c;
index = idx;
dist = d;
}
}



In the example the itmList has all the QwtPlotItems and with rtti() it checks if a QwtPlotItem is a QwtPlotCurve. So I don't think this is the solution. It is the beginning though.

jesse_mark
24th June 2013, 17:38
yeah you right it check if it a curve or not, then checking the closest point

go more done using the curve closest point and distance;
u can fined your selected curve.


if ( curve && dist < 10 ) // 10 pixels tolerance
{
d_selectedCurve = curve;
d_selectedPoint = index;
showCursor( true );
}

Christoss
24th June 2013, 17:59
You are also right, but still this finds only when the user clicks on a point. I'd like to select the line between the points as well

jesse_mark
24th June 2013, 19:48
well, this way its all depends :
- the Distance Between different Points on a curve(DBP),
- the Distance Between the different Curves(DBCs).

you may just need to use better tolerance distance to meet your needs. (if DBP is less than the DBCs ).

Uwe
24th June 2013, 21:20
Also have a look at the curvetracker example - maybe you find some interesting code snippet there too.

Uwe

Christoss
5th July 2013, 17:06
Thank you for your answers, I used a mathematical equation that finds if the mouse point is on the line between the curves

lwz
21st July 2013, 04:05
I have looked into the curvetracker example and practiced . However , it can only locate the point on a straight line between two points without deviation . Deviation comes while the curve is set myplot->setCurveAttribute(QwtPlotCurve::Fitted) .

Any idea to fix this problem?
Thanks in advance !!

Uwe
21st July 2013, 16:34
Well, the fitter creates temporary points in paint device coordinates, that are not known to the picker. What you could do is to apply the spline interpolation to your points in plot coordinates ( using QwtSplineCurveFitter::fitCurve() manually ) passing the interpolated points instead. The curvetracker code works out of the box - but of course this is a different type of interpolation.

If you don't want to do this you could overload QwtSplineFitter::fitCurve() and store the interpolated points:


class YourSplineFitter: public QwtSplineFitter
{
public:
virtual QPolygonF fitCurve( const QPolygonF &points ) const
{
mInterpolatedPoints = QwtSplineFitter::fitCurve( points );
return mInterpolatedPoints;
}

...
private:
QPolygonF mInterpolatedPoints;
};

Then the CurveTracker can be implemented using mInterpolatePoints.

HTH,
Uwe

lwz
23rd July 2013, 12:32
Thanks ,it works much better