PDA

View Full Version : Custom CurveStyle for qwt_plot_curve



jmsbc
11th April 2009, 01:56
Hi,

I needed to inherit from qwt_plot_curve to add another CurveStyle (DottedLines) to the enum:



/*
- UserCurve
Styles >= UserCurve are reserved for derived
classes of QwtPlotCurve that overload drawCurve() with
additional application specific curve types.
*/
enum CurveStyle
{
NoCurve,

Lines,
Sticks,
Steps,
Dots,

UserCurve = 100
};


I wanted to make a style called DottedLine, which connects every other point with a line. I need to derive a class and then redefine DrawCurve:



void QwtPlotCurve::drawCurve(QPainter *painter, int style,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
switch (style)
{
case Lines:
if ( testCurveAttribute(Fitted) )
{
// we always need the complete
// curve for fitting
from = 0;
to = dataSize() - 1;
}
drawLines(painter, xMap, yMap, from, to);
break;
case Sticks:
drawSticks(painter, xMap, yMap, from, to);
break;
case Steps:
drawSteps(painter, xMap, yMap, from, to);
break;
case Dots:
drawDots(painter, xMap, yMap, from, to);
break;
case DottedLines:
drawDottedLines(painter, xMap, yMap, from, to);
break;
case NoCurve:
default:
break;
}
}

(I added drawDottedLines at the bottom). How can I inherit the enum CurveStyles such that I can set the style using:

void QwtPlotCurve::setStyle(CurveStyle style)?

I can't inherit the enum right? Do I need to redefine setStyle to:

void MyPlotCurve::setStyle(MyCurveStyle style)? And if so, how do I define MyCurveStyle?

I hope this is not too confusing, thanks

Uwe
11th April 2009, 09:57
class YourCurve: public QwtPlotCurve
{
enum YourStyle
{
DottedLines = QwtPlotCurve::UserStyle + 1000
}

....

virtual void drawCurve(QPainter *painter, int style,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
if ( style < QwtPlotCurve::UserStyle )
QwtPlotCurve::drawCurve(painter, style, xMap, yMap, from, to);
else
drawYourCurve(painter, style, xMap, yMap, from, to);
}
};

HTH,
Uwe

jmsbc
15th April 2009, 03:14
Thanks Uwe!

Now that I got that problem solved, I'm trying to connect every other point in the QwtPlotCurve. I added a function for drawing DottedLines, which looks like this:


void MyQwtPlotCurve::drawDottedLines(QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
if (!connectLine)
{
prevX = xMap.transform(to);
prevY = yMap.transform(to);
connectLine = true;
} else
{
const int xi = xMap.transform(x(to));
const int yi = yMap.transform(y(to));

QwtPainter::drawLine(painter, prevX, prevY, xi, yi);
connectLine = false;
}


The bool connectLine is just a counter to keep track of drawing for every other point. Also, the parameters "from" and "to" are always equal to each other. I was trying to implement something like DrawSticks, but this isn't quite working correctly. A line keeps getting drawn from the last point to some crazy point. What am I doing wrong, please help!

Thanks a lot again

Uwe
15th April 2009, 06:57
prevX = xMap.transform(to);
prevY = yMap.transform(to);


Mapping an index - did you look at your code yourself ?

But if "from" is always the same as "to" you have degenerated curves consisting of one point ( what is a marker ). Don't do this.

Uwe

jmsbc
15th April 2009, 18:49
prevX = xMap.transform(to);
prevY = yMap.transform(to);


Mapping an index - did you look at your code yourself ?

But if "from" is always the same as "to" you have degenerated curves consisting of one point ( what is a marker ). Don't do this.

Uwe
Sorry about that, I was testing a bunch of different code in that function, so I didn't catch that mistake.

After going back to debug the code, I realized that drawDottedLines is not only called when I explicitly call draw(int from, int to), but it is called to repaint the canvas each time the canvas changes from a paintevent. So then I realized every point or line in the curve need to be re-drawn each time drawDottedLines(...) gets called. (When I was debugging before, for some reason I saw that "from" and "to" were always the same number so I thought one point was being painted at a time)

Here's the code which works now:

void MyQwtPlotCurve::drawDottedLines(QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
for (int i = from; i <= to; i++)
{
if (((i+1) % 2) == 0)
{
const int prevX = xMap.transform(x(i - 1));
const int prevY = yMap.transform(y(i - 1));
const int xi = xMap.transform(x(i));
const int yi = yMap.transform(y(i));

QwtPainter::drawLine(painter, prevX, prevY, xi, yi);
}
}

Thanks again Uwe