Call Qt QGraphicsView :: setViewport with a custom QGLWidget

I got from QGLWidget before, for example:

class MyGLWidget : public QGLWidget { public: // stuff... virtual void initializeGL() { /* my custom OpenGL initialization routine */ } // more stuff... }; 

However, I found that if I try to initialize a QGraphicsView using my custom QGLWidget as a viewport, initializeGL will not be called (setting a breakpoint in the Qt library will also not QGLWidget :: initializeGL () when creating is simple).

 // initializeGL, resizeGL, paintGL not called ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer))); // initializeGL, resizeGL, paintGL *still* not called ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer))); 

Where is the correct location to host the code that is currently in MyGLWidget :: initializeGL ()?

+4
source share
5 answers

I am going to answer and answer my question. This is not optimal, but that is exactly how I ran into the problem.

Instead

 ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer))); 

I have this instead:

 ui.graphicsView->setViewport(new QGLWidget(new CustomContext(QGLFormat(QGL::SampleBuffers)))); 

CustomContext is a class derived from QGLContext. I overridden the create element, for example:

 virtual bool create(const QGLContext *shareContext = 0) { if(QGLContext::create(shareContext)) { makeCurrent(); /* do my initialization here */ doneCurrent(); return true; } return false; } 

I do not think that this is the best way to do this, but it is better than an alternative to the lack of a specific initialization stage. I would still be happy if someone left a better answer!

0
source

A custom QGraphicsView setupViewport slot can be used to call updateGL () on a QGLWidget, which will call initializeGL ().

 class MyGraphicsView : public QGraphicsView { //... The usual stuff protected slots: virtual void setupViewport(QWidget *viewport) { QGLWidget *glWidget = qobject_cast<QGLWidget*>(viewport); if (glWidget) glWidget->updateGL(); } }; 
+4
source

So, I found that QGraphicsView sets a custom eventFilter in the QGLWidget viewport, so it never sees the initialize / resize / repaint event. This was probably done to work correctly with drawBackground (), etc.

My best solution is to catch the desired event either in QGraphicsView :: resizeEvent () / etc, or set your own eventFilter in your derived QGLWidget class to catch the resize / paint / etc events before the custom eventFilter QGraphicsView swallows them.

+2
source

Pain, pain, ... integrating widgets derived from QGlWidgets into QGraphicsView is not fun, from the parts of Qt that I know, this is definitely one of the dirtier areas. I ended up using the kgllib part (from kde) called widgetproxy, which is a very decent wrapper around QGlWidget. I modified it to fit my needs, but it works well enough for most general cases when you want to use an existing class derived from QGlWidget inside a QGraphicsView and draw other things on top of it.

+1
source

initializeGL() will not be called until the first call is either paintGL() or resizeGL() , and not when the widget is created. This can happen as long as the widget first becomes visible.

0
source

All Articles