PDA

View Full Version : Plotting data with QwtPlotOpenGLCanvas



r2com
16th August 2016, 21:20
Trying to get simple first template example for plotting using the brand new QwtPlotOpenGLCanvas class which is based on QOpenGLWidget

I was trying to get necessary parts from the refreshtest example.

Here is what I have first separately in my widget.cpp as a declaration:

class GLCanvas: public QwtPlotOpenGLCanvas
{
public:
GLCanvas( QwtPlot *parent = NULL ):
QwtPlotOpenGLCanvas( parent )
{
setContentsMargins( 1, 1, 1, 1 );
}

protected:
virtual void paintEvent( QPaintEvent *event )
{
QPainter painter( this );
painter.setClipRegion( event->region() );

QwtPlot *plot = qobject_cast< QwtPlot *>( parent() );
if ( plot )
plot->drawCanvas( &painter );

painter.setPen( palette().foreground().color() );
painter.drawRect( rect().adjusted( 1, 1, 0, 0 ) );
}
};


then inside of the Widget constructor I have this code:

QwtPlotOpenGLCanvas *plotCanvas = qobject_cast<QwtPlotOpenGLCanvas *>( canvas() );
if ( plotCanvas == NULL )
{
plotCanvas = new GLCanvas();
plotCanvas->setPalette( QColor( "yellow" ) );

setCanvas( plotCanvas );

}

Here are my concerns/questions:

1) When I tried the above experiment with old QwtPlotGLCanvas, I did have a proper widget with yellow colored canvas. So I assume it was working. But after I changed it to be QwtPlotOpenGLCanvas based, mo matter what palette I set with

plotCanvas->setPalette( QColor( "yellow" ) );
the color is always black, why? Is it a bug, or am I supposed to set something more when changing to QwtPlotOpenGLCanvas ?

2) How to plot data now? For example, before, without OpenGL, we would do something like this

QwtPlot *plot = new QwtPlot(this);
and then create a curve and do

curve->attach( plot );
However; right now I cannot attach curve like that because it will complain that argument to the attach function is not of QwtPlot * type, so How am I supposed to do it properly?

Uwe
16th August 2016, 21:49
Trying to get simple first template example for plotting using the brand new QwtPlotOpenGLCanvas class which is based on QOpenGLWidget
Note, that the implementation is not done - so don't expect it being as stable as you can expect for the other Qwt classes. And better don't start with modifying the refreshtest example - AFAIR something is broken in combination with QOpenGLWidget ( black content ) - any other example should be fine.

Also don't expect too much from QOpenGLWidget - it is using the same paint engine as the QGLWidget. I can even imagine QGLWidget being slightly faster for your use case because of not buffering to an internal FBO.On the other side interactive elements ( f.e rubberbands ) do work with QOpenGLWidget only, but a standard QWidget seems to be even better for that use case.

How to plot data now?
There is no difference - the problem you have described is in your application code.

Uwe

r2com
16th August 2016, 23:08
Alright Uwe, I think I have worked it out. Here is a code of my widget, can you tell me if it looks like an OK method to plot using the OpenGL capability through your QwtPlotOpenGLCanvas method (at least it runs and displays properly, with right colors as well):



Widget::Widget(QwtPlot *parent) :
QwtPlot(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);

QwtPlotOpenGLCanvas *plotCanvas = new QwtPlotOpenGLCanvas();
plotCanvas->setPalette( QColor("khaki") );
setTitle("Test Plot");
setCanvas( plotCanvas );

setAxisScale( QwtPlot::yLeft, 0.0, 10.0 );
setAxisScale( QwtPlot::xBottom, 0.0, 7.0 );
insertLegend( new QwtLegend() );
QwtPlotGrid *grid = new QwtPlotGrid();
grid->attach( this );

QwtPlotCurve *curve = new QwtPlotCurve();
curve->setTitle( "Some Points" );
curve->setPen( Qt::blue, 4 ),
curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );

QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse,
QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) );
curve->setSymbol( symbol );

QPolygonF points;
points << QPointF( 0.0, 4.4 ) << QPointF( 1.0, 3.0 )
<< QPointF( 2.0, 4.5 ) << QPointF( 3.0, 6.8 )
<< QPointF( 4.0, 7.9 ) << QPointF( 5.0, 7.1 );
curve->setSamples( points );

curve->attach( this );

resize( 600, 400 );
show();
}

Specifically, is what I do in lines #33, #16, #5 and especially line #7 is normal thing to do in order to achieve this plotting? My whole Widget is based on QwtPlot.

Uwe
17th August 2016, 16:40
Sure, simply assign a different type of canvas - that's all.

When working with trunk you might also want to check QwtPlotCurve::FilterPointsAggressive. When flooding a oscilloscope alike plot with many points this filter might improve the performance significantly ( regardless of the type of canvas ).

Uwe

r2com
17th August 2016, 18:41
Quick question, does the new QwtPlotOpenGLCanvas support all the zooming features?

found that it does, created another topic not to contaminate this thread, here: http://www.qtcentre.org/threads/66621-QwtPlotOpenGLCanvas-Zooming-huge-delays-when-Widget-is-fullscreen?p=292809#post292809