PDA

View Full Version : mouse tracking showing float numbers



fatecasino
17th January 2011, 02:32
I have a 2d data to plot.
The x-values range from 0 to 2000
The y-values range 2e-11 to 4e-9
The mouse tracker works perfectly for the x-values but it shows always 0.000 for the y-values. Is there a way to show float precision values on the mouse tracker?

PS: I have done an experiment with both x and y values in the range of e-11 and the mouse tracker shows always 0.000 for both values

FelixB
17th January 2011, 10:16
write your own picker and overload the virtual "trackerText()"-method. Then you can define the number format which is used in the string (see QString::number())

here is an example from my code. I'm using it in a spectrogram to show not only the position but also the value under the cursor. Also I want to have a semi-alpha background (otherwise the text would sometimes be hard to read)

QwtText PlotPicker::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "," + QString::number(pos.y()) + ") " + QString::number(m_spectrogram.ValueAt(pos.x(), pos.y())));
QColor bgColor(Qt::black);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));
return text;
}

fatecasino
17th January 2011, 14:59
how do you implement this in your code? I am based on the bode example, so I have a class for 2d plots called my2dPlot.


QwtPlot *myPlot;
QwtPlotGrid *grid;

QwtPlotCurve *mainCurve;
QwtPlotMarker *mainCurveMarker;

QwtPlotCurve *continuumCurve;
QwtPlotMarker *continuumCurveMarker;
QwtPlotMarker *myMarker;

QwtPlotZoomer *m_zoomer;
QwtPlotPicker *d_picker;
QwtPlotPanner *d_panner;

QwtDoubleRect workingRect;

I suppose I have to include the new function in the header file.



QwtText trackerText (const QwtDoublePoint & pos) const;


Then adjust your code in the .cpp file

QwtText my2dPlot::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "," + QString::number(pos.y()) + ") " + QString::number(myPlot.ValueAt(pos.x(), pos.y())));
QColor bgColor(Qt::black);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));
return text;
}

in the my2dPlot constructor I used to have a common picker/texttracker

d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::PolygonRubberBand, QwtPicker::AlwaysOn,
myPlot->canvas());
d_picker->setStateMachine(new QwtPickerPolygonMachine());
d_picker->setRubberBandPen(QColor(Qt::green));
d_picker->setTrackerPen(QColor(Qt::blue));
d_picker->setTrackerFont(f);

How can i apply the new trackerText in the constructor?

d_stranz
17th January 2011, 18:27
What FelixB means is that you have to write your -own- picker class (derived from QwtPlotPicker) and reimplement the trackerText method. You then use an instance of your new picker class -instead- of the standard QwtPlotPicker.

Notice that in the example FelixB gave, trackerText is not a member of the QwtPlot class, it is a member of his PlotPicker class.

The code you posted is simply wrong. There -is- no trackerText in the QwtPlot class, so writing a new one in a derived class will do absolutely nothing since nothing ever calls it.

fatecasino
26th January 2011, 15:36
I think I managed to create my own class myPicker.



class myPicker : public QwtPlotPicker
{
public:

myPicker(QwtPlot::Axis xAxis, QwtPlot::Axis yAxis, QwtPicker::RubberBand rb, QwtPicker::DisplayMode dm, QwtPlotCanvas* canvas):
QwtPlotPicker( xAxis, yAxis, rb , dm , canvas)
{

setStateMachine(new QwtPickerPolygonMachine());
setRubberBandPen(QColor(Qt::green));
//d_picker->setRubberBand(QwtPicker::PolygonRubberBand);
setTrackerPen(QColor(Qt::yellow));
//setTrackerFont(f);



}


QwtText trackerText (const QwtDoublePoint & pos) const;

};


QwtText myPicker::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "," + QString::number(pos.y()) + ") ");
QColor bgColor(Qt::black);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));
return text;
}

and i created my object like this:


d_picker = new myPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::PolygonRubberBand, QwtPicker::AlwaysOn,
myPlot->canvas());

I have two very basic questions..
1.how do i use my new function trackerText (const QwtDoublePoint & pos) const
2.When i use the myPlot private member



QwtText text("(" + QString::number(pos.x()) + "," + QString::number(pos.y()) + ") " + QString::number(myPlot.ValueAt(pos.x(), pos.y()))); QColor bgColor(Qt::black);

i get that myPlot is undeclared. How did FelixB used it with m_spectrogram without getting any error?

FelixB
26th January 2011, 16:01
1.how do i use my new function trackerText (const QwtDoublePoint & pos) const
you don't have to use it. since QwtPlotPicker::trackerText is declared virtual, it gets called automatically


2.When i use the myPlot private member [...] How did FelixB used it with m_spectrogram without getting any error?

I passed the plot as parameter to the constructor of myPicker. m_spectrogram is a member of my PlotPicker. But I don't think you need that... it was just a demonstration from my code.

fatecasino
26th January 2011, 18:21
ok, I removed the QString::number(myPlot.ValueAt(pos.x(), pos.y())


class PlotPicker : public QwtPlotPicker
{
public:

PlotPicker(QwtPlot::Axis xAxis, QwtPlot::Axis yAxis, QwtPicker::RubberBand rb, QwtPicker::DisplayMode dm, QwtPlotCanvas* canvas):
QwtPlotPicker( xAxis, yAxis, rb , dm , canvas)
{

setStateMachine(new QwtPickerPolygonMachine());
setRubberBandPen(QColor(Qt::green));
//d_picker->setRubberBand(QwtPicker::PolygonRubberBand);
//setTrackerPen(QColor(Qt::yellow));
//setTrackerFont(f);
}

QwtText trackerText (const QwtDoublePoint & pos) const;

};

QwtText PlotPicker::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "...," + QString::number(pos.y()) + ") " );
QColor bgColor(Qt::blue);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));
return text;
}

but the function trackerText is never actually called. I changed several parameters (colour, text, etc) but nothing happens!

FelixB
27th January 2011, 07:58
show the code where you create and install the picker, please...

fatecasino
27th January 2011, 15:13
i have created a widget called my2dPlot to plot 2d data sets:
my2dPlot.h

class my2dPlot : public QWidget
{
Q_OBJECT

public:
my2dPlot(QWidget *parent = 0);
......
private:
QwtPlot *myPlot;
QwtPlotGrid *grid;

QwtPlotCurve *mainCurve;
QwtPlotMarker *mainCurveMarker;

QwtPlotZoomer *m_zoomer;
QwtPlotPicker *d_picker;//<-----
QwtPlotPanner *d_panner;
....
}

then in the my2dPlot.cpp


class PlotPicker : public QwtPlotPicker
{
public:
PlotPicker(QwtPlot::Axis xAxis, QwtPlot::Axis yAxis, QwtPicker::RubberBand rb, QwtPicker::DisplayMode dm, QwtPlotCanvas* canvas):
QwtPlotPicker( xAxis, yAxis, rb , dm , canvas)
{

setStateMachine(new QwtPickerPolygonMachine());
setRubberBandPen(QColor(Qt::green));
//d_picker->setRubberBand(QwtPicker::PolygonRubberBand);
//setTrackerPen(QColor(Qt::yellow));
//setTrackerFont(f);
}
private:
QwtText trackerText (const QwtDoublePoint & pos) const;

};

QwtText PlotPicker::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "...," + QString::number(pos.y()) + ") " );
QColor bgColor(Qt::blue);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));
return text;
}
//i have created my own zoomer, copying the "bode" example
class Zoomer: public QwtPlotZoomer
{
public:
Zoomer(int xAxis, int yAxis, QwtPlotCanvas *canvas):
QwtPlotZoomer(xAxis, yAxis, canvas)
{
setTrackerMode(QwtPicker::AlwaysOff);
setRubberBand(QwtPicker::NoRubberBand);

// RightButton: zoom out by 1
// Ctrl+RightButton: zoom out to full size

setMousePattern(QwtEventPattern::MouseSelect2,
Qt::RightButton, Qt::ControlModifier);
setMousePattern(QwtEventPattern::MouseSelect3,
Qt::RightButton);
}
};



my2dPlot::my2dPlot(QWidget *parent)
: QWidget(parent)
{

.....
myPlot = new QwtPlot;
m_zoomer = new Zoomer( QwtPlot::xBottom, QwtPlot::yLeft,myPlot->canvas());
d_picker = new PlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::PolygonRubberBand, QwtPicker::AlwaysOn,
myPlot->canvas());
.....
}

FelixB
27th January 2011, 15:54
have you checked if trackerText gets called? I suggest you add a debug output there... (or you set a breakpoint if your ide supports them)

another idea: do you set a color for the picker? try


d_picker->setTrackerPen(QColor(Qt::darkGreen));

fatecasino
28th January 2011, 01:04
well, as I told you the trackerText never gets called.
I added a breakpoint but nothing happens.
I can change the colour of the picker font normally (not if i insert it in the trackerText function)
any suggestions? check the code above

FelixB
28th January 2011, 08:09
that's really strange.

you could try to change the declaration, but I don't think that'll make a difference:

PlotPicker *d_picker;//<-----

this is my initialization:

d_picker = new PlotPicker (QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::PointSelection | QwtPicker::DragSelection, QwtPlotPicker::NoRubberBand, QwtPicker::AlwaysOn, plot->canvas());
d_picker->setTrackerPen(QColor(Qt::darkGreen));

and my constructor is empty:

PlotPicker ::PlotPicker (int xAxis, int yAxis, int selectionFlags, RubberBand rubberBand, DisplayMode trackerMode, QwtPlotCanvas* canvas)
: QwtPlotPicker(xAxis, yAxis, selectionFlags, rubberBand, trackerMode, canvas)
{
}

and my trackerText is declared "protected" instead of "private", but that definitively does not make a difference (I checked that)

fatecasino
29th January 2011, 14:57
i have done everything right, but for a very well hidden reason it does not work!


my2dPlot.h

class my2dPlot : public QWidget
{
Q_OBJECT

public:
my2dPlot(QWidget *parent = 0);

private:
QwtPlot *myPlot;
QwtPlotGrid *grid;

QwtPlotCurve *mainCurve;

PlotPicker *d_picker;
....
}

my2dPlot.cpp

d_picker = new PlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::PolygonRubberBand, QwtPicker::AlwaysOn,
myPlot->canvas());
d_picker->setStateMachine(new QwtPickerPolygonMachine());

PlotPicker.h

class PlotPicker : public QwtPlotPicker
{
public:

PlotPicker (int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QwtPlotCanvas* canvas);

private:
QwtText trackerText (const QwtDoublePoint & pos) const;

};

PlotPicker.cpp


#include <plotPicker.h>

PlotPicker ::PlotPicker (int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QwtPlotCanvas* canvas)
: QwtPlotPicker(xAxis, yAxis, rubberBand, trackerMode, canvas)
{

setTrackerPen(QColor(Qt::yellow));//testing if this constructor is called


}


QwtText PlotPicker::trackerText (const QwtDoublePoint & pos) const
{
QwtText text("(" + QString::number(pos.x()) + "...," + QString::number(pos.y()) + ") " );
QColor bgColor(Qt::blue);
bgColor.setAlpha(160);
text.setBackgroundBrush(QBrush(bgColor));

return text;
}


The tracker pen is yellow, which means that the constructor of the PlotPicker is called indeed. However, the trackerText function is totally ignored!!
any ideas?!

d_stranz
29th January 2011, 19:23
Do you call the QwtPicker::setEnabled( true ) method anywhere?

fatecasino
31st January 2011, 03:19
yes,I have an "enablePickerMode" button, which enables/disables the picker.
When I press it I can see that the picker works fine,
i can select a polygon and I can see the plot values (but the float number like e-12 are represented as 0.0000 and the trackerText function is never called)


void my2dPlot::enablePickerMode(bool on)
{

d_picker->setEnabled(on);

}

FelixB
31st January 2011, 08:08
which version of qwt are you using? I have 5.2. Maybe something has changed in 6.0. have a look into the sources of qwtplotpicker.h to and check the declaration of TrackerText()...

fatecasino
1st February 2011, 20:24
I use the QWT Release 6.0.

searching in my QWT folder i found this in the qwt_plot_picker.cpp



QwtText QwtPlotPicker::trackerText( const QPoint &pos ) const
{
return trackerTextF( invTransform( pos ) );
}

/*!
\brief Translate a position into a position string

In case of HLineRubberBand the label is the value of the
y position, in case of VLineRubberBand the value of the x position.
Otherwise the label contains x and y position separated by a ',' .

The format for the double to string conversion is "%.4f".

\param pos Position
\return Position string
*/
QwtText QwtPlotPicker::trackerTextF( const QPointF &pos ) const
{
QString text;

switch ( rubberBand() )
{
case HLineRubberBand:
text.sprintf( "%.4f", pos.y() );
break;
case VLineRubberBand:
text.sprintf( "%.4f", pos.x() );
break;
default:
text.sprintf( "%.4f, %.4f", pos.x(), pos.y() );
}
return QwtText( text );
}

is there an obvious reason I cannot overload these functions? should I just go manually and change them?!

Added after 15 minutes:

I FOUND IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Ι should overload the trackerTextF function and not the trackerText!!!
I realized it when I saw the source code of the qwt_plot_picker
:);)

d_stranz
2nd February 2011, 15:40
I use the QWT Release 6.0.

Oh boy. Another "gotcha" when moving from Qwt 5.x to 6.0. I hope these kinds of things are going to be documented...

Sorry fatecasino, all of our answers were based on Qwt 5.2, where your trackerText() code should have worked perfectly.