前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FFmpeg】SDL 音视频开发 ③ ( SDL 事件处理 | SDL_Event 数据结构分析 | 事件处理流程 | SDL 事件获取函数 | SDL_WaitEvent 函数 )

【FFmpeg】SDL 音视频开发 ③ ( SDL 事件处理 | SDL_Event 数据结构分析 | 事件处理流程 | SDL 事件获取函数 | SDL_WaitEvent 函数 )

作者头像
韩曙亮
发布2024-06-21 13:44:08
790
发布2024-06-21 13:44:08
举报

博客源码下载 : https://download.csdn.net/download/han1202012/89432451

SDL 事件处理代码执行效果如下 :

一、SDL 事件处理简介

1、SDL 事件处理引入

SDL , Simple DirectMedia Layer , 是 跨平台的多媒体开发库 , 用于开发 跨平台 的 多媒体应用程序 , 可开发 WIndows / Linux / MacOS 多媒体应用 , 编写一次代码 , 可以在多个平台运行 ;

使用 SDL 多媒体库开发的 应用 有如下功能 :

  • 窗口创建
  • 图像绘制
  • 视频播放
  • 音频播放
  • 事件处理

其中的 事件处理 , 就是处理 外设 ( 键盘 / 鼠标 ) 传入的事件 , 如 鼠标移动 , 鼠标点击 , 键盘按键 等事件 ;

2、SDL 事件处理步骤

SDL 事件处理步骤 :

  • 首先 , 调用 SDL_Init 函数 , 初始化 SDL 环境 , 设置要开发的子系统 ;
  • 然后 , 调用 SDL_CreateWindow 函数创建窗口 ;
  • 再后 , 处理事件 , 开启一个事件循环 , 不断调用 SDL_PollEvent 函数 , 获取是否有事件发生 , 如果获取到了键盘/鼠标事件 , 则执行对应的操作 ;
  • 最后 , 用户触发退出操作 , 则退出事件循环 , 并 调用 SDL_Quit 函数 , 释放 SDL 资源并退出 ;

代码示例 :

执行结果 : 运行程序后 , 弹出窗口 ,

此时开启循环 , 监听事件 , 每次循环时有事件发生 , 就会进入 if (event.type == SDL_QUIT) 分支语句 ,

点击窗口中右上角的 x 关闭按钮 , 会触发 SDL_QUIT 事件 , 此时退出事件循环 ,

继续执行代码就会关闭窗口 , 释放 SDL 资源 , 程序运行结束 ;

运行程序后弹出事件窗口 :

点击 窗口中的 关闭按钮 , 就会触发 SDL_QUIT 事件 ;

二、SDL 事件数据结构分析

1、SDL_Event 事件 - union 联合体

SDL_Event 用于存储各种事件 , 事件有如下类型 :

  • 键盘事件
  • 鼠标事件
  • 手柄事件
  • 窗口事件
  • 手势事件
  • 传感器事件

具体类型 , 在下面的 SDL_Event 联合体的代码注释中有详细说明 ;

SDL_Event 是一个联合体 定义在 SDL_event.h 头文件中 , 该 SDL_Event 联合体是一种特殊的数据结构 , 允许在相同的内存位置存储不同类型的数据 ;

完整的 SDL_Event 联合体 union 内容如下 :

代码位置 :

2、SDL_Event 事件处理流程

SDL_Event 联合体设计很巧妙 , 其第一个类型成员 Uint32 type 与 其它 25 个结构体类型成员 共同占用同一个内存空间 , 这 25 个结构体 的第一个参数也都是 Uint32 type 成员 ;

因此 , 不管是什么类型的 事件 , 都可以通过 获取 Uint32 type 成员 , 获得该成员的类型 , 然后根据该类型 , 就知道这是什么事件 , 直接调用该事件对应的结构体即可 ;

举例说明 : 获取的 SDL_Event 事件对象 的 Uint32 type 类型是键盘事件 SDL_KEYDOWN , 那么就使用 SDL_KeyboardEvent 结构体的 数据格式 访问该 SDL_Event 事件 ;

SDL_KeyboardEvent 结构体内容如下 :

解析键盘事件的代码示例如下 : 调用 SDL_WaitEvent 函数 , 阻塞等待事件到来 , 事件到来后 ,

  • 首先 , 获取事件的类型 , event.type , 先看是哪种类型的事件 , 选择使用哪种结构体数据格式访问改事件数据 ;
  • 然后 , 如果获取的事件是 SDL_KEYDOWN 键盘事件 , 则使用 SDL_KeyboardEvent 结构体的数据格式访问 SDL_Event 事件对象 ;
  • 最后 , 通过访问 SDL_KeyboardEvent 结构体的 event.key.keysym.sym 成员 , 获取按下的是哪个按键 , 根据不同的按键 , 进行不同的操作 ;

三、SDL 事件函数

1、SDL_PollEvent 函数

在上面的示例中 , 使用了 SDL_PollEvent 函数 , 检测是否有事件发生 ,

  • 如果有事件发生 , 则通过参数中的 SDL_Event 指针返回该事件 , 函数返回值 1 ;
  • 如果没有事件发生 , 函数返回 0 , SDL_Event 指针参数不变 ;

SDL_PollEvent 函数 是 非阻塞函数 , 如果没有事件发生 , 则立刻返回 , 不会阻塞程序执行 ; 与之相对的是 SDL_WaitEvent 函数 , 该函数会阻塞程序 , 等待事件发生 ;

SDL_PollEvent 函数原型如下 :

  • event 参数 : 指向 SDL_Event 对象的指针 , 如果有事件 , 则通过该参数获取事件 ;
  • int 返回值 : 如果获取事件成功 , 则返回 1 ; 如果获取事件失败 , 返回 0 ;

代码示例 : 使用 SDL_PollEvent 函数时 ,

  • 首先 , 声明 SDL_Event 变量 ;
  • 然后 , 将 SDL_Event 变量地址传入 SDL_PollEvent 函数 ;
  • 最后 , 根据 SDL_PollEvent 函数的返回值 , 决定是否处理事件 ;
    • 如果返回 1 , 则处理事件 ;
    • 如果返回 0 , 则不处理事件 ;

2、SDL_WaitEvent 函数

SDL_WaitEvent 函数 的作用是 阻塞等待事件发生 , 如果没有事件发生 , 则程序会一直阻塞等待下去 , 当有事件发生时 , 再继续向下执行 ;

SDL_WaitEvent 函数原型如下 :

  • event 参数 : 指向 SDL_Event 对象的指针 , 如果有事件 , 则通过该参数获取事件 ;
  • int 返回值 : 如果获取事件成功 , 则返回 1 ;

如果没有事件发生 , 则程序会一直阻塞下去 ;

代码示例 : 使用 SDL_WaitEvent 函数的流程如下 :

  • 首先 , 定义 SDL_Event 事件变量 ;
  • 然后 , 调用 SDL_WaitEvent 函数 , 传入 SDL_Event 变量的地址 , 使用 取地址符 & 获取变量地址 ;

调用了 SDL_WaitEvent 函数后 , 会阻塞当前的程序 , 直到 事件发生 , 解除阻塞继续执行 ;

四、完整代码示例

博客源码下载 : https://download.csdn.net/download/han1202012/89432451

1、代码示例

代码示例 :

2、执行结果

执行结果 :

鼠标移动 , 触发的事件 :

键盘按键 , 触发的事件 :

鼠标点击触发的事件 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、SDL 事件处理简介
    • 1、SDL 事件处理引入
      • 2、SDL 事件处理步骤
      • 二、SDL 事件数据结构分析
        • 1、SDL_Event 事件 - union 联合体
          • 2、SDL_Event 事件处理流程
          • 三、SDL 事件函数
            • 1、SDL_PollEvent 函数
              • 2、SDL_WaitEvent 函数
              • 四、完整代码示例
                • 1、代码示例
                  • 2、执行结果
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档