PDA

View Full Version : Distance measuring in plot.



thejester
5th May 2011, 07:34
Hi,

I'm trying to create a distance measure tool, that will display the delta X and delta Y values of 2 points within the plot, and draw a line between these two points.

I started out with some old code from (http://www.qtcentre.org/archive/index.php/t-10367.html). Some changes were needed to get it running in Qwt6.


class DistancePicker : public QwtPlotPicker
{
public:
DistancePicker( QwtPlotCanvas * canvas )
:QwtPlotPicker( canvas )
{
setStateMachine( new QwtPickerClickRectMachine );
setRubberBand( PolygonRubberBand );
setTrackerMode( QwtPicker::ActiveOnly );
}

protected:
virtual void drawRubberBand(QPainter* painter) const
{
painter->drawPolygon( selection() );
}

virtual QwtText trackerText (const QPoint& pos) const
{
const QPolygon& polygon = selection();

if ( polygon.size() != 2 )
{
return QwtText();
}

const QLineF line(invTransform(polygon[0]), invTransform(polygon[1]));

QwtText text( QString::number(line.length()) );

QColor bg(Qt::white);
bg.setAlpha(180);
text.setBackgroundBrush(QBrush(bg));

return text;
}
};

While this seems to be working good, i do have a few problems with it.
1) Depending on where you move the second selection for the measurement, the measurement picker text runs through the default picker that that always displays the current x,y position. Is there something to do about that ?
2) When we zoom in to the plot, just after releasing the mouse for the zoom action, the plot zooms in to new selection, and then automagically a measurement is started.
Is it possible to do measurements only when user presses space bar for instance ?

Thanks for any help !

TJ

Uwe
5th May 2011, 07:58
1) Depending on where you move the second selection for the measurement, the measurement picker text runs through the default picker that that always displays the current x,y position. Is there something to do about that ?
The implementation of DistancePicker::trackerText is your code. Do you have another picker displaying this text ( f.e. the zoomer ).

2) When we zoom in to the plot, just after releasing the mouse for the zoom action, the plot zooms in to new selection, and then automagically a measurement is started.
Maybe you are using the same mouse events for the zoomer and your distance picker. You can redefine them using QwtEventPattern::setMousePattern/setKeyPattern.

Is it possible to do measurements only when user presses space bar for instance ?
Use QwtEventPattern::setMousePattern() and redefine the input events for your distance picker.

Uwe

thejester
5th May 2011, 08:24
Indeed the other text that is displayed, belongs to the zoomer. But when I attach the DistancePicker, i have no control over, where exactly, the text is displayed right ? DistancePicker knows nothing about zoomer ? Or am i missing something.

The zoomer, is a default zoomer. Only changes were made to restrictions on y zoom.

Since zooming is done with left button, i wanted to add your setMousePattern and select events ONLY when control key pressed and right mouse (instead of the left mouse button). So in constructor i added setMousePattern( QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier );
But now, measuring is done when control is not pressed, and ignored when it is :)

Must be missing something really stupid here, or I might need more coffee. :)

Uwe
6th May 2011, 10:22
More coffee !

Uwe

thejester
6th May 2011, 10:49
Instead of more coffee i think i need joint or something.....

when i throw : setMousePattern( QwtEventPattern::MouseSelect4, Qt::LeftButton, Qt::NoButton ); in the zoomer, and
setMousePattern( QwtEventPattern::MouseSelect2, Qt::LeftButton, Qt::NoButton ); in the distancepicker

i would have expected different behavior than described above... ?
what am i doing wrong ?

Uwe
6th May 2011, 12:00
Instead of more coffee i think i need joint or something.....
... really boring like reading the 2 lines of documentation ?

QwtPickerClickRectMachine implements a state machine with an input alphabet of 2 symbols:

QwtEventPattern::MouseSelect1
QwtEventPattern::KeySelect1.


So don't be surprised, that changing the mouse/key bindings of other symbols doesn't have any effect on this state machine.

Uwe

thejester
6th May 2011, 12:24
Uwe,

I can understand your frustration, i assume its as big as mine :)

You said : Use QwtEventPattern::setMousePattern() and redefine the input events for your distance picker.
I looked up, where the setMousePattern could be called on, and discovered that QwtPlotPicker is derived from QwtEventPattern. Since my DistancePicker is a QwtPlotPicker i assumed calling the setMousePattern in DistancePicker's constructor would do it.

I see now that all is handled through the statemachines.

For me, as qwt newbie, its still confusing why QwtPlotPicker is derived from QwtEventPattern then.

But anyway, ill create my own QwtPickerClickRectMachine for the distance picker then.

Thanks for all help !

Uwe
6th May 2011, 13:36
I see now that all is handled through the statemachines.
Not all - the picker translates real mouse/key events into something abstract like QwtEventPattern::MouseSelect1 etc. Then this abstract symbol is handled by the state machine.

You can easily implement your own state machine - f.e, when you want to terminate your selection with a different input as you have started it. But as long as you start and terminate your measurement with the same operations there is no need to implement your own state machine: all you need to do is to redefine QwtEventPattern::MouseSelect1, so that it doesn't interfere with your zoomer.

You can call the whole system a bit "over-engineered" - but in the end it is very flexible and powerful.

Something you should always have in mind when you are dealing with open source software: instead of playing hours around with parameters of a method you can always try to look into the implementation of this method.

Uwe