SDL事件处理不起作用

4

我目前正在通读Lazy Foo教程学习SDL。在Linux上,我使用的是Code Blocks 13.12。然而,我无法正确地处理事件。

基本上我试图显示一张图片(这个很好用),但是无论我点击多少次关闭按钮都不会关闭。

代码:

#include <SDL2/SDL.h>
#include <stdio.h>
//Declaring the main window, the main surface and the image surface
SDL_Window *window = NULL;
SDL_Surface *scrsurface = NULL;
SDL_Surface *imgSurface = NULL;
SDL_Event event;
int run = 1;

//The function where SDL will be initialized
int init();
//The function where the image will be loaded into memory
int loadImage();
//The function that will properly clean up and close SDL and the variables
int close();

//The main function
int main(void){
    if(init() == -1)
        printf("Init failed!!!");
    else{
        if(loadImage() == -1)
            printf("loadImage failed!!!");
        else{

            //Displaying the image

            while(run){
                //Event handling
               while(SDL_PollEvent(&event)){
                    switch(event.type){
                        case SDL_QUIT:
                            run = 0;
                            fprintf(stderr, "Run set to 0");
                            break;
                        default:
                            fprintf(stderr, "Unhandled event");
                         break;
                    }
                } 
                //Blitting nad updating
                SDL_BlitSurface(imgSurface, NULL, scrsurface, NULL);
                SDL_UpdateWindowSurface(window);
            }
        close();

        }
    }
    return 0;

}

int init(){
 if(SDL_Init(SDL_INIT_VIDEO) < 0)
    return -1;
 else{
    window = SDL_CreateWindow("SDL_WINDOW", SDL_WINDOWPOS_UNDEFINED,  SDL_WINDOWPOS_UNDEFINED, 900, 900, SDL_WINDOW_SHOWN);
    if(window == NULL)
        return -1;
    scrsurface = SDL_GetWindowSurface(window);

}
return 0;
}


int loadImage(){
    imgSurface = SDL_LoadBMP("Test.bmp");
    if(imgSurface == NULL)
        return -1;
    else{

    }
    return 0;
}

int close(){
    SDL_FreeSurface(imgSurface);
    SDL_DestroyWindow(window);
    window = NULL;
    SDL_Quit();
    return 0;

}

`


另外,fprintf 函数在标准输出流和标准错误流上都不会显示任何内容。 - Shahe Ansar
通常情况下,将您的非静态函数命名为“close”是一个非常糟糕的想法,因为它与libc的“close(int)”别名重复,并且Xlib / SDL在尝试关闭其文件描述符时可能会调用您的函数。这很可能是您看不到任何打印内容的原因,甚至可能更多问题的根源。 - keltar
谢谢,老兄,那个方法可行!希望你能把它作为答案发布。 - Shahe Ansar
2个回答

1
尝试将close();移动到while (run)循环结束后,而在// Blitting nad updating之前。同时,将SDL_BlitSurface(imgSurface, NULL, scrsurface, NULL);和SDL_UpdateWindowSurface(window);移动到其他位置,因为它们会在程序停止运行后运行,并且在将run设置为0后,所有代码都将在此之后运行。

实际上,close()在while(run)循环结束后立即执行,而blitting和其他操作则在循环内部执行。 - Shahe Ansar
尝试从关闭函数中删除 window = null。 - Java Man Tea Man
“Won't close”是什么意思?当你将鼠标悬停在窗口上时,是否有一个加载圆圈(我不知道它在Linux上如何工作,但该窗口是否投射出一个动画表示正在“加载”?),还是窗口在你点击关闭按钮后没有消失? - Java Man Tea Man
它简单地不会消失,fprintf也不会显示在控制台上,而且close()没有循环也可以正常工作,所以我怀疑那不是问题。 - Shahe Ansar
但是您能够点击关闭按钮,对吧?尝试添加另一个输入,例如SDL_KEYDOWN。 - Java Man Tea Man

1
虽然需要仔细调试以确定发生了什么,但你的问题很可能是由于libc的close函数与你的函数重命名引起的。许多库(包括SDL)使用了非常重要的调用close,例如SDL_CreateWindow调用XOpenDisplay/XCloseDisplay来测试显示器的功能,但XCloseDisplay会在其连接套接字上调用close,并且它将调用你的函数而不是原来的函数。很难说之后会发生什么,但肯定不是预期的结果。
解决方法要么是将函数重命名为其他名称(例如通过添加前缀),要么将其声明为static,以便其名称不被导出。请注意,静态函数只能在单个翻译单元中使用(即,如果您的.c文件包含静态函数,则无法轻松地从另一个.c文件中使用它)。
链接器在此处没有报告多个定义,因为libc的close是弱符号(nm -D /lib/libc.so.6 | egrep ' close$'报告W)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接