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

多显示器配置变更时Qt应用因glWaitSync访问冲突崩溃

崩溃原因分析
  1. Qt 5.15.2 ANGLE后端已知缺陷:Qt 5.15.2版本中,ANGLE后端处理显示配置变更(跨DPI显示器移动窗口、分辨率调整)时,D3D11设备重置逻辑存在bug。当系统触发DXGI_ERROR_DEVICE_REMOVED(设备被移除)信号时,ANGLE未能正确清理或重建同步对象,导致后续调用glWaitSync时出现内存访问违规(ACCESS_VIOLATION)。
  2. 跨DPI上下文同步失效:QWebEngineView的父控件绑定到主显示器的ui.widgetPms,窗口跨不同DPI显示器移动后,Qt的DPI缩放上下文与ANGLE的D3D11设备上下文不同步,设备重置时资源引用失效,触发崩溃。
解决方案

1. 升级Qt版本(优先推荐)

Qt 5.15.3及后续补丁版本(如5.15.12)修复了多个QWebEngine与ANGLE后端相关的显示配置变更崩溃问题。若无法迁移到Qt 6,建议升级到Qt 5.15系列的最新稳定补丁版。

2. 切换到桌面OpenGL后端

强制应用使用桌面OpenGL替代ANGLE,规避D3D11设备重置的兼容性问题:

  • 在QApplication实例化之前添加代码:
    #include <QCoreApplication>
    
    int main(int argc, char *argv[]) {
        QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); // 强制使用桌面OpenGL
        QApplication a(argc, argv);
        // ... 其他业务代码
        return a.exec();
    }
    
  • 或通过环境变量设置:启动应用前配置QT_OPENGL=desktop

3. 监听显示变更事件,重建QWebEngineView

检测到显示配置变更时,手动销毁并重建QWebEngineView,避免无效资源引用:

  • 在PmsDialogWidget中添加监听与重建逻辑:
    // PmsDialogWidget.h
    class PmsDialogWidget : public QWidget {
        Q_OBJECT
    private slots:
        void recreateWebView();
    private:
        QWebEngineView* webView = nullptr;
        QWebChannel* webChannel = nullptr;
        // ... 其他成员变量
    };
    
    // PmsDialogWidget.cpp
    PmsDialogWidget::PmsDialogWidget(QWidget* parent) : QWidget(parent) {
        ui.setupUi(this);
        this->setWindowFlags(Qt::FramelessWindowHint);
        this->setAttribute(Qt::WA_StyledBackground, true);
        
        connect(this, &QWidget::screenChanged, this, &PmsDialogWidget::recreateWebView);
        recreateWebView(); // 首次初始化
    }
    
    void PmsDialogWidget::recreateWebView() {
        // 销毁原有控件
        delete webView;
        delete webChannel;
    
        // 重新创建并初始化
        webView = new QWebEngineView(ui.widgetPms);
        webChannel = new QWebChannel(ui.widgetPms);
        // 恢复WebView状态(如加载URL、绑定WebChannel等)
        webView->page()->setWebChannel(webChannel);
        // webView->load(QUrl("your-target-url"));
    }
    
    注意:此方法会丢失WebView当前状态(如页面内容、表单数据),需根据业务需求添加状态保存与恢复逻辑。

4. 调整高DPI缩放策略

  • 禁用高DPI缩放(妥协方案,高分辨率显示器上界面会模糊):
    QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
    
  • 或强制使用系统级DPI缩放:
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    
    确保所有显示器使用相同缩放比例,可减少跨DPI场景的冲突。

5. 更新显卡驱动

NVIDIA旧版本驱动可能存在D3D11设备重置的兼容性问题,将RTX 750i的驱动更新到最新稳定版,可解决部分DXGI_ERROR_DEVICE_REMOVED触发的崩溃。


内容的提问来源于stack exchange,提问作者wenshu wu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:15:13