PDA

View Full Version : Issue placing a QOpenGLWidget in a QDockWidget



sandytf
10th January 2015, 20:36
I'm having an issue placing a subclassed QOpenGLWidget inside a QDockWidget and was wondering if anyone else is experiancing a similar problem. When the example code below is run, the QMainWindow and the QDockWidget appear as expected. However, once the QDockWidget is dragged over the QMainWindow and docked, there is an unhandled exception. I think the problem may involve the OpenGL context changing or getting destroyed. When debugging with Visual Studio 2013 Update 4, the debugger breaks into QOpenGLFunctions_4_3_Core::glClearColor and the d_1_0_core variable appears to be invalid. I tried making the OpenGLWidget class use QOpenGLFunctions_4_3_Core as a member variable (instead of using inheritance) and recreating it each time initializeGL was called, but that seemed to just make the problem worse.

System: Windows 7 64-bit
Compiler: Visual Studio 2013 Update 4
Configuration: 32-bit debug
Qt: 5.4

MainWindow.h


#ifndef __MAIN_WINDOW__
#define __MAIN_WINDOW__

// Forward declarations
class QDockWidget;
class OpenGLWidget;

// System includes
#include <QMainWindow>

class MainWindow : public QMainWindow{
Q_OBJECT

public:
MainWindow(QWidget * pParent = nullptr);

protected:
OpenGLWidget * m_pOpenGLWidget = nullptr;
QDockWidget * m_pDockWidget = nullptr;
};

#endif


MainWindow.cpp

#include "MainWindow.h"

// System includes
#include <QDockWidget>

// Application includes
#include "OpenGLWidget.h"

MainWindow::MainWindow(QWidget * pParent) : QMainWindow(pParent){
m_pOpenGLWidget = new OpenGLWidget(this);
m_pDockWidget = new QDockWidget("OpenGL Dock", this);
m_pDockWidget->setWidget(m_pOpenGLWidget);
m_pDockWidget->setFloating(true);
resize(300, 300);
}


OpenGLWidget.h


#ifndef ___OPENGL_WIDGET___
#define ___OPENGL_WIDGET___

// System includes
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_3_Core>

class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core{
public:
explicit OpenGLWidget(QWidget * pParent = nullptr) : QOpenGLWidget(pParent) {setFixedSize(200, 200);}

protected:
virtual void initializeGL() Q_DECL_OVERRIDE{
if(!initializeOpenGLFunctions()) qFatal("Failed to initialize the OpenGL functions.");
glClearColor(0, 0, 0, 1);
}
};

#endif


Main.cpp


// System includes
#include <QApplication>

// Application includes
#include "MainWindow.h"

int main(int argc, char ** argv){
QApplication app(argc, argv);
MainWindow mainWindow;

mainWindow.show();
return(app.exec());
}

sandytf
25th January 2015, 15:11
The problem was related to the context getting destroyed and corrupting the QOpenGLFunctions base class. I found a work-around where the QOpenGLFunctions is used via a member variable instead of via multiple inheritance. The updated OpenGLWidget.h file is below.



#ifndef ___OPENGL_WIDGET___
#define ___OPENGL_WIDGET___

// System includes
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_3_Core>

class OpenGLWidget : public QOpenGLWidget{
public:
explicit OpenGLWidget(QWidget * pParent = nullptr) : QOpenGLWidget(pParent) {setFixedSize(200, 200);}
~OpenGLWidget() {DeleteFunctions();}

protected:
void DeleteFunctions() {delete(m_pFunctions); m_pFunctions = nullptr;}

virtual void initializeGL() Q_DECL_OVERRIDE{
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &OpenGLWidget::DeleteFunctions);

m_pFunctions = new QOpenGLFunctions_4_3_Core();
if(!m_pFunctions->initializeOpenGLFunctions()) qFatal("Failed to initialize the OpenGL functions.");
glClearColor(0, 0, 0, 1);
}

QOpenGLFunctions_4_3_Core * m_pFunctions = nullptr;
};

#endif