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

C++ SDL2:打开第二个窗口后键盘输入失效(单窗口模式正常)

问题分析与解决方案

你的问题其实很好定位——你只处理了SDL_QUIT事件,却完全忽略了窗口关闭的SDL_WINDOWEVENT_CLOSE事件。

为什么单窗口正常、多窗口失效?

在单窗口模式下,部分SDL版本或Linux桌面环境会在唯一窗口被关闭时,自动触发SDL_QUIT事件,让你的程序能正常退出。但当存在多个窗口时,SDL不会因为单个窗口关闭就发送SDL_QUIT——这个事件只有在所有窗口都关闭,或者系统发出全局退出请求(比如某些桌面环境的全局快捷键)时才会触发。所以你点击任意一个窗口的关闭按钮,程序根本没收到退出信号,自然会继续运行。

修复代码

只需要在你的事件循环里添加对SDL_WINDOWEVENT_CLOSE的处理即可。下面是修改后的事件循环部分:

while (Run) {
    while (SDL_PollEvent (&Event)) {
        // 处理全局退出请求
        if (Event.type == SDL_QUIT) {
            Run = false;
        }
        // 处理单个窗口的关闭按钮事件
        else if (Event.type == SDL_WINDOWEVENT) {
            if (Event.window.event == SDL_WINDOWEVENT_CLOSE) {
                // 这里可以选择两种逻辑:
                // 1. 只要有一个窗口关闭就退出整个程序(直接设Run为false)
                Run = false;
                // 2. 关闭对应窗口并继续运行其他窗口(需要给Window类加状态标记,比如isActive,然后在Refresh时判断是否跳过)
            }
        }
    }
    W1.Refresh ();
    W2.Refresh ();
    SDL_Delay (1000 / 60);
}

额外的优化建议

除了修复核心问题,还有几个小细节可以优化:

  • 合并SDL初始化调用:你现在重复调用了四次SDL_Init,其实可以一次性初始化所有需要的子系统,这样更简洁也更易维护:
    if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
        cerr << "SDL初始化失败: " << SDL_GetError() << "\n";
        return 1;
    }
    
  • 添加Renderer创建失败的错误处理:在Window::Init里,你只检查了窗口创建失败的情况,但如果Renderer创建失败(比如GPU不支持),会导致后续Refresh时访问空指针崩溃。可以加上:
    if (UseGPU) {
        Renderer = SDL_CreateRenderer(W, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);
        if (Renderer == NULL) {
            cerr << "Renderer创建失败: " << SDL_GetError() << "\n";
            SDL_DestroyWindow(W);
            return 1;
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:39:05