首页 > 解决方案 > SDL2 窗口不会立即关闭?

问题描述

#include "SDL.h"
#include "SDL_image.h"
#include <iostream>

const int width = 800, height = 600;

int main(int argc, char* argv[]) 
{
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        std::cout << "SDL couldn't initialise! Error: " << SDL_GetError() << std::endl;
    }

    SDL_Window* window = SDL_CreateWindow("New Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_ALLOW_HIGHDPI);

    if (window == NULL) 
    {
        std::cout << "Window couldn't be created! Error: " << SDL_GetError() << std::endl;
        return EXIT_FAILURE;
    }

    SDL_Event windowEvent;

    while (true)
    {
        if (SDL_PollEvent(&windowEvent))
        {
            if (SDL_QUIT == windowEvent.type)
            {
                break;
            }
        }
    }

    SDL_DestroyWindow(window);
    SDL_Quit();

    return EXIT_SUCCESS;
}

那么在这个小程序中,窗口是如何保持打开的呢?我已经尝试了保持它打开的方法,并发现它是这部分:

    while (true)
    {
        if (SDL_PollEvent(&windowEvent))
        {
            if (SDL_QUIT == windowEvent.type)
            {
                break;
            }
        }
    }

更具体地说,循环在“真”时循环。但我不明白什么是真的,也不知道它是如何循环的。有人可以解释它是如何工作的吗?如果有人基本上逐步解释了这里的所有内容,我将不胜感激。(例如“SDL_Window”是什么,SDL_Event 是什么等)

标签: c++windowsdlsdl-2

解决方案


除非我读错了问题,否则这似乎是一个非常笼统的 C++ 语言问题与 SDL 问题混合在一起。我只想在这里指出,SDL 需要足够的 c++ 知识,因此如果您不自信,您可能很快就会遇到更多障碍。

无论如何,在 c++ 中,while(expression) { ... } 循环将继续循环,而括号中的“表达式”评估为真。如果你想永远循环,你可以通过写这个来强制表达式为真:while(true) { ... }。退出这个循环的唯一方法是从循环内部调用“break”命令。一旦程序跳出循环,程序将到达主“return 0;”。并安全退出。

至于这条线:

if (SDL_PollEvent(&windowEvent))

每次运行此行时,SDL 都会检查是否有任何“事件”准备好进行处理。事件是从 SDL 或您的操作系统发送到您的应用程序的“消息”,以使您的应用程序执行某些操作。在您的代码中,您正在检查窗口事件的“IE 轮询”。需要明确的是,当用户(您)单击窗口关闭按钮、最小化、最大化、调整窗口大小等时,这些事件将被发送到您的应用程序。当收到其中一条消息时,此行将返回 true。弄清楚事件是什么以及你想用它做什么是你的工作。

这些行:

if (SDL_QUIT == windowEvent.type)
{
    break;
}

将检查收到的事件类型。如果事件类型是 SDL_QUIT(IE 用户按下窗口上的关闭按钮),则“break”命令将被执行。如前所述,如果调用了break,它将退出循环,应用程序将关闭。

所以总而言之,你的代码将进入一个无限循环,因为它的表达式总是评估为真(真 ==真)。在循环中,我们检查是否有新事件。如果我们确实得到了一个事件,请弄清楚它是什么。如果它是 SDL_QUIT,则从循环中中断。如果我们“*没有”得到一个事件,那么只需重新循环并再次检查一个事件。


推荐阅读