无法从 window 获取 SDL2 事件
cant get SDL2 event's from window
我正在尝试使用 C++ 学习 SDL。我有一个简单的程序可以显示图像。但是当我尝试通过单击 window 上的关闭按钮来关闭 window 时,没有任何反应。
这是我的代码:-
#include <SDL2/SDL.h>
int main(int argc,char **argv)
{
static int k =0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *w;
w = SDL_CreateWindow("SDL VS Works",300,300,400,500,SDL_WINDOW_OPENGL);
SDL_Renderer *render = SDL_CreateRenderer(w,-1,SDL_RENDERER_ACCELERATED);
SDL_Surface *tux = SDL_LoadBMP("res/tux.bmp");
SDL_Texture *texture = SDL_CreateTextureFromSurface(render,tux);
SDL_FreeSurface(tux);
SDL_ShowWindow(w);
SDL_Event event;
while(1)
{
k++;
printf("Running and loop %d\'th\n",k);
SDL_PollEvent(&event);
if(event.type == SDL_QUIT)
{
printf("closing \n");
goto sos;
}
SDL_RenderCopy(render,texture,0,0);
SDL_RenderPresent(render);
SDL_Delay(1000);
}
sos:
SDL_DestroyWindow(w);
SDL_DestroyRenderer(render);
SDL_DestroyTexture(texture);
SDL_Quit();
}
我在 Arch Linux 上使用 g++ 7.3。
SDL 在内部使用事件队列。当 any 事件发生时,就像鼠标移动了几个像素一样,它被添加到队列中。当您轮询事件时(使用 SDL_PollEvent
),您只会得到最早的事件。其他一切都留在队列中。
由于您的代码每秒只轮询一次,队列可能会被鼠标移动淹没,而 SDL_QUIT
事件只是在排队等候,深入队列。
您通常想做的是循环轮询事件。请注意 SDL_PollEvent
returns 0 当没有未决事件时。
while (SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT)
{
//...
}
}
顺便说一句,循环应该是这样的:
SDL_Event SDLEvent;
while (SDL_PollEvent(&SDLEvent))
{
switch (SDLEvent.type)
{
case SDL_QUIT: break;
case SDL_WINDOWEVENT: break;
case SDL_MOUSEMOTION: break;
case SDL_MOUSEWHEEL: break;
}
}
无论是像这样的 switch 语句还是像您那样的 if 语句都不重要。如果队列中仍有事件,SDL_PollEvents 将 return 为 1,否则为零。通过在 while 条件中调用 SDL_PollEvents(&SDLEvent) 它将在进入下一个 while 块之前处理队列中的所有事件。
有趣的是,您的 window 无法关闭的问题似乎与其他问题有关,因为它对我有用。我已经提到也许可以去掉 SDL_Delay 行,看看是否有任何作用;
我正在尝试使用 C++ 学习 SDL。我有一个简单的程序可以显示图像。但是当我尝试通过单击 window 上的关闭按钮来关闭 window 时,没有任何反应。
这是我的代码:-
#include <SDL2/SDL.h>
int main(int argc,char **argv)
{
static int k =0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *w;
w = SDL_CreateWindow("SDL VS Works",300,300,400,500,SDL_WINDOW_OPENGL);
SDL_Renderer *render = SDL_CreateRenderer(w,-1,SDL_RENDERER_ACCELERATED);
SDL_Surface *tux = SDL_LoadBMP("res/tux.bmp");
SDL_Texture *texture = SDL_CreateTextureFromSurface(render,tux);
SDL_FreeSurface(tux);
SDL_ShowWindow(w);
SDL_Event event;
while(1)
{
k++;
printf("Running and loop %d\'th\n",k);
SDL_PollEvent(&event);
if(event.type == SDL_QUIT)
{
printf("closing \n");
goto sos;
}
SDL_RenderCopy(render,texture,0,0);
SDL_RenderPresent(render);
SDL_Delay(1000);
}
sos:
SDL_DestroyWindow(w);
SDL_DestroyRenderer(render);
SDL_DestroyTexture(texture);
SDL_Quit();
}
我在 Arch Linux 上使用 g++ 7.3。
SDL 在内部使用事件队列。当 any 事件发生时,就像鼠标移动了几个像素一样,它被添加到队列中。当您轮询事件时(使用 SDL_PollEvent
),您只会得到最早的事件。其他一切都留在队列中。
由于您的代码每秒只轮询一次,队列可能会被鼠标移动淹没,而 SDL_QUIT
事件只是在排队等候,深入队列。
您通常想做的是循环轮询事件。请注意 SDL_PollEvent
returns 0 当没有未决事件时。
while (SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT)
{
//...
}
}
顺便说一句,循环应该是这样的:
SDL_Event SDLEvent;
while (SDL_PollEvent(&SDLEvent))
{
switch (SDLEvent.type)
{
case SDL_QUIT: break;
case SDL_WINDOWEVENT: break;
case SDL_MOUSEMOTION: break;
case SDL_MOUSEWHEEL: break;
}
}
无论是像这样的 switch 语句还是像您那样的 if 语句都不重要。如果队列中仍有事件,SDL_PollEvents 将 return 为 1,否则为零。通过在 while 条件中调用 SDL_PollEvents(&SDLEvent) 它将在进入下一个 while 块之前处理队列中的所有事件。
有趣的是,您的 window 无法关闭的问题似乎与其他问题有关,因为它对我有用。我已经提到也许可以去掉 SDL_Delay 行,看看是否有任何作用;