You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Qt6后QOpenGLContext调用非OpenGL表面报错及UI异常

问题概述
  • 环境配置:
    • Ubuntu 24.04
    • OCC 7.8.1
    • Qt 6.4.2
  • 场景:QTabWidget包含两个标签页,第一个关联QPushButton,第二个关联继承自QOpenGLWidget的OccQtViewer(承载OCC渲染逻辑)
  • 问题:切换到第二个标签页后UI混乱、标签无响应,控制台输出警告:
    QOpenGLContext::makeCurrent() called with non-opengl surface 0x5c468b22deb0
    QRhiGles2: Failed to make context current. Expect bad things to happen.
    
  • 对比情况:Windows+Qt6、Linux+Qt5下运行正常,仅Linux+Qt6出现问题;尝试过设置窗口SurfaceType但未解决。
解决方案

针对Linux下Qt6与OCC的OpenGL上下文冲突问题,可按以下步骤修复:

1. 提前设置主窗口的Surface类型

在窗口显示前,强制将主窗口的Surface设置为OpenGL类型,避免Qt默认使用其他渲染后端:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    if (w.windowHandle()) {
        w.windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
    }
    w.show();
    return a.exec();
}

2. 管控OpenGLWidget的上下文生命周期

重写OccQtViewer的showEvent和hideEvent,确保切换标签时上下文正确激活/释放:

void OccQtViewer::showEvent(QShowEvent* event)
{
    QOpenGLWidget::showEvent(event);
    if (context()) {
        context()->makeCurrent(this);
        if (myView) {
            myView->Redraw();
        }
        context()->doneCurrent();
    }
}

void OccQtViewer::hideEvent(QHideEvent* event)
{
    QOpenGLWidget::hideEvent(event);
    if (context()) {
        context()->doneCurrent();
    }
}

3. 强制Qt6使用OpenGL后端

在main函数开头添加环境变量,禁用Qt6默认的非OpenGL渲染后端:

int main(int argc, char *argv[])
{
    qputenv("QT_OPENGL", "desktop");
    qputenv("QT_QUICK_BACKEND", "opengl");
    
    QApplication a(argc, argv);
    MainWindow w;
    // ...后续代码
}

4. 延迟OCC初始化到OpenGL上下文就绪后

将OCC的视图初始化逻辑从OccQtViewer的构造函数移到initializeGL中,确保在OpenGL上下文完全创建后再初始化OCC资源:

void OccQtViewer::initializeGL()
{
    QOpenGLWidget::initializeGL();
    Handle(Aspect_DisplayConnection) displayConn;
    myContext = new V3d_Viewer(displayConn);
    myView = myContext->CreateView();
    myView->SetBackgroundColor(Quantity_NOC_GRAY);
    // 其他OCC初始化操作...
}
问题原因

Qt6在Linux平台默认可能采用Vulkan或其他非OpenGL渲染后端,导致QOpenGLWidget的上下文与窗口Surface不兼容;同时QTabWidget切换时,OpenGLWidget的上下文未被正确管理,OCC的渲染逻辑尝试在无效上下文下执行,引发UI异常。

内容的提问来源于stack exchange,提问作者Alex Luya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:42:45