【问题标题】:SDL_MOUSEBUTTONUP occurring even before releasing mouse button?SDL_MOUSEBUTTONUP 甚至在释放鼠标按钮之前发生?
【发布时间】:2018-03-07 16:19:05
【问题描述】:

我正在尝试在 C++ 中使用 SDL 和 ffmpeg 制作视频播放器。我创建了两个单独的线程,一个在 SDL 窗口上呈现视频,一个用于处理窗口事件。当用户单击并释放视频时,我希望它切换播放/暂停。但是,它会触发多次,甚至在我释放鼠标之前就发生了事件,这会导致不可预知的行为。

我的代码:

SDL_Event event;

    while (1)
    {
        SDL_PollEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                SDL_DestroyWindow(screen);
                SDL_Quit();
                break;
            case SDL_MOUSEBUTTONUP:
                if (event.button.state == SDL_RELEASED)
                {
                    printf("Mouse released\n");
                }
                break;
        }
    }

当我单击窗口并按住不放时,我希望它不会打印Mouse released,直到我释放按钮。但是,在我按住鼠标按钮的整个过程中,它都会打印Mouse released。我不知道这是否与我在笔记本电脑上使用触摸板有关。

【问题讨论】:

  • 请发布您的问题的最小示例。
  • @Aram 我添加了一个例子。
  • SDL_PollEvent 有一个返回值。这可能被证明是非常有用的。
  • @IInspectable 哇,太尴尬了……这就是我没有彻底阅读文档的结果。它解决了我的问题,如果你把它变成一个答案,我会接受它。非常感谢。

标签: c++ mouseevent sdl-2


【解决方案1】:

SDL_PollEvent 有返回值,你忽略了。

[It] 如果有任何未决事件,则返回 1,如果没有可用事件,则返回 0。

根据您的代码逻辑,只要没有未决事件,您就会一遍又一遍地处理前一个事件,直到新事件到来。这会导致观察到的行为。

最简单的解决方法是将整个事件处理包装在 if (SDL_PollEvent(&event)) { /* Event handling */ } 条件中。

【讨论】:

    【解决方案2】:

    编辑:我的答案是错误的,请检查 IInspectable 的答案。

    您的错误是您没有检查 pollEvent 给出的所有未决事件,只是一个。试试这段代码,告诉我你得到了多少个按钮。

    #include <SDL2/SDL.h>
    #include <iostream>
    
    
    int main(int argc, char *argv[]) {
        if(SDL_Init(SDL_INIT_VIDEO) != 0) {
            throw std::runtime_error("SDL failed to initialize.\n");
        }
    
        SDL_Window *window = SDL_CreateWindow("App", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, NULL);
    
        bool done = false;
    
        while(!done) {
            SDL_Event event;
    
            while(SDL_PollEvent(&event)) {
                if(event.type == SDL_QUIT) {
                    done = true;
                }
    
                if (event.type == SDL_MOUSEBUTTONUP) {
                    if (event.button.state == SDL_RELEASED) {
                        printf("Mouse released\n");
                    }
                }
            }
        }
    
        SDL_DestroyWindow(window);
    
        SDL_Quit();
    
        return 0;
    }
    

    【讨论】:

    • 解释有误。 OP 肯定会检索所有未决事件。真正的问题是,他们没有检查是否有任何 new 事件(通过检查返回值),因此一遍又一遍地重复处理相同的事件,直到一个新的事件到了。
    猜你喜欢
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    相关资源
    最近更新 更多