c - 为什么我的窗口只有在我使用 SDL_PollEvent() 后才会显示?
问题描述
我在 C 中使用 SDL2 并想在屏幕上显示一些东西而不需要输入。但是当我运行代码以呈现黑屏时,窗口不会打开。我继续做我知道会让它弹出并添加一个SDL_Event
变量并使用SDL_PollEvent()
. 我想知道为什么我必须这样做,以及是否有办法让我使用 aSDL_Window
而无需轮询任何事件。
(例如:类似动画的东西)。
有问题的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
int main()
{
if (SDL_Init(SDL_INIT_VIDEO))
{
fprintf(stderr, "Error while Initalizing SDL2: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
SDL_Window *window = SDL_CreateWindow("Connect Four", 100, 100, 500, 500, SDL_WINDOW_SHOWN);
if (!window)
{
fprintf(stderr, "Error while Initalizing window: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!renderer)
{
SDL_DestroyWindow(window);
fprintf(stderr, "Error while Initalizing renderer: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
SDL_Event events; //without these two lines
SDL_PollEvent(&events); //the window will not open on screen
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
解决方案
这可能会令人困惑,因为一些 SDL 示例(包括 SDL doc wiki)使用“draw&delay”代码而没有事件处理,但这不是在屏幕上显示内容的可靠方式。这些示例过于简化,并且是很久以前编写的,当时它有点工作,但仅用于最简单的事情,因为 3 秒可能不足以让窗口管理器杀死无响应的程序,或者让用户注意到窗口图像崩溃,如果它是被其他窗口最小化或覆盖。
对您的问题的简短回答是否定的,您的程序必须与窗口管理器通信(旁注 -在某些操作系统/图形系统上可能不需要);您必须获取事件并对特殊窗口事件做出反应(例如,您的窗口变得可见或用户请求调整大小)。在 SDL 中,这是通过call 完成的,它在内部进行此通信并生成您可以稍后检查的事件队列,因此您需要经常调用它,直接或间接通过orSDL_PumpEvents
SDL_PollEvent
SDL_WaitEvent
. 如果你不这样做,窗口管理器可能不会对你好 - 根据窗口管理器,你可能会得到“应用程序没有响应,让我们杀死它”对话框,灰色的窗口,或者像你的情况一样,根本没有窗口(这种特殊情况是因为您在收到“您的窗口现在可见”事件之前已经呈现了渲染结果,因此您的图像被丢弃;这就是为什么在渲染之前处理事件会改变事情的进展)。
但即便如此,处理事件一次也不正确。你所拥有的仍然是乐观的“让我们希望在 3 秒内不会发生任何破坏”。如果你做动画,处理每一帧的事件;但如果您有静态显示代码 - 将其视为动画也可能是个好主意。基本上,您需要渲染循环,在开始时进行事件处理,并在必要时重绘代码以重新生成图像。这种“必须”可能是无条件的(每次迭代都完全重绘),或者,如果你真的不想这样做(例如,出于处理成本的原因——大多数 GUI 程序在空闲时不会完全重绘)你仍然必须当窗口管理器说您以前的图像不再有效时重绘 - SDL 通过SDL_WindowEventSDL_WINDOWEVENT_EXPOSED
类型通知您。SDL_WaitEvent
以避免不必要的迭代。
推荐阅读
- macos - 如何在mac终端中创建一个循环以相反的顺序触摸文件
- regex - Oracle 18c - REGEXP_REPLACE 的替代品
- javascript - 如何从 Javascript 中的 vuetify 多选 v-autocomplete 中选择(复选框)一个值?
- algorithm - 将循环分成更小的部分
- html - 如何延迟 Angular doCheck 执行,直到用户的值完全输入到输入中?
- python - 如何在树形图上添加 % 信息?
- r - How to create a binary variable for logistic regression by using key words in text variable
- excel - 我想用一个变量来引用一个控制对象
- vb.net - 2个PDF MemorStreams的iText7合并不起作用
- sql-server - SQL Server - 在 TRANSACTION 上设置超时/自动回滚