PDA

View Full Version : Problem with selecting qwtplotcurve and points on qwtplotcurve



tangtao_xp
9th May 2013, 08:16
Greetings,

I have several qwtplotcurve attaced on a qwtplot, and it must responds mouseEvent: single left click on the curve to pick up the closest point of the curve, and double left click on curve to select the whole curve. Whatever selected, it should be hightlighted(change the color of the selected point or curve).

For two days, I searched on google, I got some useful information:

1. to track a point: use QwtPlotPicker and connect the selected signal with a slot
2. to find closest point: call QwtPlotCurve::closestPoint()

My questions are:

1. QwtPlotPicker is able to track all the points on canvas, but unable to track for a specific area(a rectangle, a line, a circle), only I just want to track the points on the curve, return me the object/pointer of the selected point.

2. If there is several curve on the plot, how could I tell the point from which curve(the curves may cross each other)

3. QwtPlotPicker can pick up a point, but how do I do to select a curve? (get the object/pointer of the curve)


Thank you in advance.


Tang Tao

Uwe
9th May 2013, 12:08
... only I just want to track the points on the curve, return me the object/pointer of the selected point.
The event_filter example does this more or less - even if this example is outdated and I wouldn't recommend to copy its code. But at least CanvasPicker::select shows how to identify a curve and its point corresponding to a mouse position.

Also similar - and more up to date - is the curvetracker example in Qwt 6.1. The itemeditor example might also be of interest, showing how to select and drag plot items on the canvas.

Uwe

tangtao_xp
10th May 2013, 03:13
Hi, Uwe

Sorry for late reply.

As your said, I will read the example of event_filter & itemeditor first, and give you the feedback soon.


Tang Tao

tangtao_xp
10th May 2013, 17:18
The event_filter example does this more or less - even if this example is outdated and I wouldn't recommend to copy its code. But at least CanvasPicker::select shows how to identify a curve and its point corresponding to a mouse position.

Also similar - and more up to date - is the curvetracker example in Qwt 6.1. The itemeditor example might also be of interest, showing how to select and drag plot items on the canvas.

Uwe


Hi, Uwe

I greatly appreciate your reply.

I had read the example code. I still have a small confusion:

code from CanvasPicker


const QwtPlotItemList& itmList = plot()->itemList();
for ( QwtPlotItemIterator it = itmList.begin();
it != itmList.end(); ++it )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve *c = static_cast<QwtPlotCurve *>( *it );
double d;
int idx = c->closestPoint( pos, &d );
if ( d < dist )
{
curve = c;
index = idx;
dist = d;
}
}
}


the for loop efficency is very low. In my situation, there will be as many curves as the user want (large number of curves) and meanwhile, I was told that closestPoint() is also low efficent. Any better ideas?

Considering the problem of curve crossing, this loop only can return one curve.(I think I am able to fix this problem by return a vector or sth like that)

Thank you in advance.

Uwe
10th May 2013, 17:43
When your samples are ordered in x or y direction you can use qwtUpperSampleIndex like in the curvetracker example: the order of this algo is logarithmic instead of linear.

But when your samples are completely random ( like in a scatter plot ) and iterating over all samples is too slow you need to introduce some spatial index - for example a quad tree.

Uwe

tangtao_xp
11th May 2013, 14:55
Hi, Uwe

Thank you very much. I do not think I can do the work without your kindly help.


Tang Tao

tangtao_xp
11th May 2013, 16:56
here is my code:

MyPicker.h


class MyPicker : public QwtPlotPicker
{
public:
MyPicker( QwtPlot *plot );

MyPicker( int xAxis = QwtPlot::xBottom,
int yAxis = QwtPlot::yLeft,
RubberBand rubberBand = CrossRubberBand,
DisplayMode trackerMode = QwtPicker::AlwaysOn,
QwtPlot *plot = NULL );

void selectPoint( const QPointF & point );
void highlightPoint( bool isHightlight );

public slots:
// slot for SIGNAL --> void selected( const QPointF &pos )
void slotSelected( const QPointF &pos);

private:
QwtPlot *m_pQwtPlot;
QwtPlotCurve *m_pSelectedCurve;
int m_selectedPointIndex;
};


MyPicker.cpp


#include "mypicker.h"

MyPicker::MyPicker(QwtPlot *plot) :
QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, CrossRubberBand, QwtPicker::AlwaysOn, plot->canvas()),
m_pSelectedCurve( NULL ),
m_pQwtPlot( plot ),
m_selectedPointIndex( -1 )
{
connect( this, SIGNAL( selected( const QPointF ) ), this, SLOT( slotSelected( const QPointF ) ) );
}

...


the QtCreator shows error:
-----------------------------------------------------------------------------------------------------

QObject::connect: No such slot QwtPlotPicker::slotSelected( const QPointF ) in ..\ttt\mypicker.cpp:9

-----------------------------------------------------------------------------------------------------

I think the problem caused by that: SIGANL selected() defined in parent class, and SLOT slotSelected() defined in subclass.

So, how should fix the problem? Thank you in advance.

tangtao_xp
12th May 2013, 03:44
here is my code:

MyPicker.h


class MyPicker : public QwtPlotPicker
{
public:
MyPicker( QwtPlot *plot );

MyPicker( int xAxis = QwtPlot::xBottom,
int yAxis = QwtPlot::yLeft,
RubberBand rubberBand = CrossRubberBand,
DisplayMode trackerMode = QwtPicker::AlwaysOn,
QwtPlot *plot = NULL );

void selectPoint( const QPointF & point );
void highlightPoint( bool isHightlight );

public slots:
// slot for SIGNAL --> void selected( const QPointF &pos )
void slotSelected( const QPointF &pos);

private:
QwtPlot *m_pQwtPlot;
QwtPlotCurve *m_pSelectedCurve;
int m_selectedPointIndex;
};


MyPicker.cpp


#include "mypicker.h"

MyPicker::MyPicker(QwtPlot *plot) :
QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, CrossRubberBand, QwtPicker::AlwaysOn, plot->canvas()),
m_pSelectedCurve( NULL ),
m_pQwtPlot( plot ),
m_selectedPointIndex( -1 )
{
connect( this, SIGNAL( selected( const QPointF ) ), this, SLOT( slotSelected( const QPointF ) ) );
}

...


the QtCreator shows error:
-----------------------------------------------------------------------------------------------------

QObject::connect: No such slot QwtPlotPicker::slotSelected( const QPointF ) in ..\ttt\mypicker.cpp:9

-----------------------------------------------------------------------------------------------------

I think the problem caused by that: SIGANL selected() defined in parent class, and SLOT slotSelected() defined in subclass.

So, how should fix the problem? Thank you in advance.


Done! Q_OBJECT is missing in the header file.

Momergil
9th February 2014, 12:37
Hello tangtao_xp,

I'm dealing with kind like the same situation of yours, but I confess I'm not as sucessfull like you to understand Qwt's example code regarding selecting and moving a QwtPlotCurve in a QwtPlot. Could you please post your complete code to this solution? (or someone else that happen to have a similar situation)


Thanks,

Momergil