PDA

View Full Version : QwtPolar picker



slux
28th September 2010, 10:01
Hi folks!
I need to display the degree and the radius value on a label every time the mouse is moved on the polar canvas. With QwtPlotPicker this is easy, but i don't see any QwtPolarPicker to do that!

I need to implement something like QwtPlotPicker? :confused:

Thanks for the help.

Uwe
28th September 2010, 21:36
Well, you could derive from QwtPicker and overload "trackerText(const QPoint &pos)".

Using the scale maps ( QwtPolarPlot::scaleMap() ) you should be able to calculate a QwtPolarPoint from pos and translate into a QString.

Uwe

larsli
10th May 2011, 10:43
Has anyone been able to do this? Been trying to do this for a day now, but do not end up with any numbers that make any sense...

slux
10th May 2011, 12:11
I post here a chunk of my code. It's not the most clear way to do that, but i mean... it works!

I use the eventFilter trapping the mouse move event on the entire canvas and translate the pixel position with the radial distance from the plot center.

I have an object that extends OQbject and thakes a QwtPolarCanvas as argument.




PolarMouseTrackerTool::PolarMouseTrackerTool(QwtPo larCanvas *canv) : QObject(canv)
{
isActive = true;
canvas = canv;
canvas->setMouseTracking(true);
canvas->installEventFilter(this);
}


And the rest of the class is this:



bool PolarMouseTrackerTool::eventFilter(QObject *obj, QEvent *event)
{
if ((event->type() != QEvent::MouseMove && event->type() != QEvent::MouseButtonRelease && event->type() != QEvent::MouseButtonDblClick) || !isActive)
{
return QObject::eventFilter(obj, event);
}

QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (mouseEvent == NULL)
return false;

QPoint mousePos = mouseEvent->pos();
QwtPolarPlot *polarPlot = canvas->plot();

if (polarPlot == NULL)
return false;

QwtScaleMap radiusMap = polarPlot->scaleMap(QwtPolar::ScaleRadius);

double sDist = radiusMap.s2() - radiusMap.s1();
double dDist = radiusMap.p2() - radiusMap.p1();

//The pole center (in pixel)
QPoint pole = polarPlot->plotRect().center().toPoint();

//translate
translatePosWithCanvasCenter(pole, mousePos);

//Pitagora
double a = qAbs(qAtan(mousePos.y() / (mousePos.x() * 1.0)));
double r = qSqrt((qPow(mousePos.x(), 2)) + qPow(mousePos.y(), 2));
translateAzimuthWithCanvasCenter(mousePos, a);

//radix mapping
r = (r * sDist) / dDist;

if (event->type() == QEvent::MouseMove)
emit signalMoved(a, r);

if (event->type() == QEvent::MouseButtonDblClick)
{
emit signalDblClicked(a, r, mouseEvent->button());
emit signalDblClicked(mouseEvent->pos(), mouseEvent->button());
}

if (event->type() == QEvent::MouseButtonRelease)
emit signalClicked(a, r, mouseEvent->button());

return true;
}

void PolarMouseTrackerTool::translatePosWithCanvasCente r(const QPoint &canvasCenter, QPoint &pos)
{
pos.setX(pos.x() - canvasCenter.x());
pos.setY(canvasCenter.y() - pos.y());
}

void PolarMouseTrackerTool::translateAzimuthWithCanvasC enter(const QPoint &pos, double &azimuth)
{
if (pos.x() >= 0 && pos.y() >= 0) //Quadrant 1
{
//Nothing to do
}
else if (pos.x() < 0 && pos.y() > 0) //Quadrant 4
{
azimuth = (M_PI / 2.0) + ((M_PI / 2.0) - azimuth);
}
else if (pos.x() <= 0 && pos.y() <= 0) //Quadrant 3
{
azimuth = M_PI + azimuth;
}
else //Quadrant 2
{
azimuth = (M_PI * (3.0 / 2.0)) + ((M_PI / 2.0) - azimuth);
}

}

Uwe
10th May 2011, 20:53
Well your class is not really derived from QwtPicker, but the basic idea of event filtering is the same and if it works for you ...

Uwe

larsli
11th May 2011, 10:37
Thanks a lot! This works for me. I tried to put the code in my own picker class, but couldn't get the numbers quite correct, propably because of small differences in the cursor position. Also this made the tracker text show up correctly (if I put return QObject::eventFilter(obj, event); at the end of the eventfilter function.) Before it would get stuck when set to AlwaysOn.

Lars