答案有点晚了,但是创建它们的线程需要将小部件移动到新线程。在您的情况下,例如:
QGLWidget *glWidget=new QGLWidget();
QThread *newThread=new QThread();
glWidget->doneCurrent();
glWidget->context()->moveToThread(newThread);
这里我只将 openGL 上下文移动到新线程,这需要捕获并忽略 QGLWidget 中的一些覆盖。您将需要从 QGLWidget 创建一个新的派生类并覆盖以下内容。
virtual void glInit();
virtual void glDraw();
virtual void initializeGL();
virtual void resizeGL(int width, int height);
virtual void paintGL();
这会阻止标准 UI 线程尝试使 OpenGL 上下文在 UI 线程中处于当前状态。一旦你覆盖了上述内容,你将需要一个事件系统来通知线程一些事件已经发生,主要是 resizeGl 和 paintGL 否则小部件将无法与周围的其他小部件正确反应。
最后一部分是创建 QGLWidget。构造中的参数之一是 const QGLWidget * shareWidget:
QGLWidget ( QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0 )
QGLWidget ( QGLContext * context, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0 )
QGLWidget ( const QGLFormat & format, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0 )
然后,您将创建 ui QGLWidget 和线程 GLWidget(从 QGLWidget 派生并具有上述所有覆盖)确保在创建线程 GLWidget 时将 QGLWidget 作为 sharedWidget 提供。这将使 2 个 opengl 上下文共享,并允许您在两者都可以看到的一个中加载纹理。代码应如下所示:
QGLWidget *glWidget=new QGLWidget();
GLWidget *threadedWidget=new GLWidget(0/*parent*/, glWidget);
QThread *newThread=new QThread();
threadedWidget->moveToThread(newThread);
至于代码,我最近使用线程 QGLWidgets 编写了一个小示例程序,主要用于 openGL/openCL 互操作,但它显示在共享单个上下文的绘制线程中使用多个 QGLWidgets。代码在github上,描述在这里http://www.krazer.com/?p=109