<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=API%2Fevent%2Fzh</id>
	<title>API/event/zh - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=API%2Fevent%2Fzh"/>
	<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=API/event/zh&amp;action=history"/>
	<updated>2026-08-24T15:14:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://ocr.michiyo.me/w/index.php?title=API/event/zh&amp;diff=1026&amp;oldid=prev</id>
		<title>imported&gt;OCDoc Import: Imported from legacy OpenComputers documentation at ocdoc.cil.li</title>
		<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=API/event/zh&amp;diff=1026&amp;oldid=prev"/>
		<updated>2026-08-24T08:08:27Z</updated>

		<summary type="html">&lt;p&gt;Imported from legacy OpenComputers documentation at ocdoc.cil.li&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Event(事件) API =&lt;br /&gt;
&lt;br /&gt;
Event(事件) API为用户提供了一套基本的事件处理系统，可利用其编写代码以响应操作系统或其他程序/运行库传递的[[Component/signals|信号]]。&lt;br /&gt;
&lt;br /&gt;
例如，你可以利用此API捕获按下的按键、在外接显示器连接到电脑或断开连接时进行响应，或是处理传入的网络信息。&lt;br /&gt;
&lt;br /&gt;
== 概述 ==&lt;br /&gt;
&lt;br /&gt;
event API主要有两种用法:&lt;br /&gt;
&lt;br /&gt;
* 让程序在后台运行时对事件作出响应(驱动模式)。 - 让程序在作为前台程序执行时处理事件(优先模式)。&lt;br /&gt;
&lt;br /&gt;
在驱动模式下，你的程序需要先为事件注册回调函数（用 `event.listen()`函数），然后退出，以继续执行主程序(通常是shell)。 在优先模式下，你无需在程序中注册事件，可以直接使用`events.pull()`函数拉取并处理信号。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注意：&amp;#039;&amp;#039;&amp;#039;虽然从技术层面上讲可以同时使用两种工作模式，但不推荐这样做。为了保证所有已注册的函数都能接收到事件，事件只有在所有函数均被调用后才会被消耗掉。因此如果你注册了处理函数，同时又进行了拉取，那么同一个事件会被响应两次。&lt;br /&gt;
&lt;br /&gt;
== 函数 ==&lt;br /&gt;
&lt;br /&gt;
* `event.listen(event: string, callback: function): boolean` 注册一个新的事件侦听器，会在指定名称的事件出现后被调用。 &amp;#039;&amp;#039;&amp;#039;event&amp;#039;&amp;#039;&amp;#039; - 需要侦听的信号名称。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;callback&amp;#039;&amp;#039;&amp;#039; - 在收到指定信号后调用的函数。此函数将会接收注册的事件名称作为第一个参数，然后接收触发事件的[[Component/signals|信号]]所定义的所有参数。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;返回值：&amp;#039;&amp;#039;&amp;#039;若注册成功，数据类型为`number`，代表了事件id，可用于传递给`event.cancel`函数取消事件。若函数已经注册过此类事件，将会返回`false`。&lt;br /&gt;
* `event.ignore(event: string, callback: function): boolean` 注销一个先前注册的事件侦听器。 &amp;#039;&amp;#039;&amp;#039;event&amp;#039;&amp;#039;&amp;#039; - 需要注销的信号名称。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;callback&amp;#039;&amp;#039;&amp;#039; - 之前注册到此事件的回调函数。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;返回值：&amp;#039;&amp;#039;&amp;#039;若事件成功注销则返回`true`。若指定的函数并未注册到此类事件则返回`false`。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注意：&amp;#039;&amp;#039;&amp;#039;事件侦听器返回`false`后将会注销自身。等价于调用 `event.ignore`，并向其传递侦听器函数与所注册的事件名称。&lt;br /&gt;
* `event.timer(interval: number, callback: function[, times: number]): number` 开启一个新的定时器，在经过`interval`指定的时长后将会被触发。 &amp;#039;&amp;#039;&amp;#039;interval&amp;#039;&amp;#039;&amp;#039; - 调用回调函数的间隔时长，单位为秒。可以为像0.05这样的小数。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;callback&amp;#039;&amp;#039;&amp;#039; - 要调用的函数。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;times&amp;#039;&amp;#039;&amp;#039; - 应调用的次数。若省略则函数只会被调用一次。指定为`math.huge`可以无限次重复调用。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;返回值：&amp;#039;&amp;#039;&amp;#039;定时器id，可以随时用于取消定时器。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注意：&amp;#039;&amp;#039;&amp;#039;定时器的精度可能会发生变化。如果电脑闲置并进入了休眠模式，则电脑只会每游戏刻唤醒一次。因此触发回调函数的时间点可能会偏差至多0.05秒。&lt;br /&gt;
* `event.cancel(timerId: number): boolean` 取消某个先前由`event.timer`函数创建的定时器。 &amp;#039;&amp;#039;&amp;#039;timerId&amp;#039;&amp;#039;&amp;#039; - 由`event.timer`函数返回的定时器id。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;返回值：&amp;#039;&amp;#039;&amp;#039;若定时器被成功终止则返回`true`。若不存在指定id对应的定时器则返回`false`。&lt;br /&gt;
* `event.pull([timeout: number], [name: string], ...): string, ...` 从队列中拉取下一个可用事件，或者等待可用事件出现。 &amp;#039;&amp;#039;&amp;#039;timeout&amp;#039;&amp;#039;&amp;#039; - 若指定了值，则函数会至多等待此秒数。超时后仍未出现可用事件，函数会返回`nil`。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039; - 目标事件的模式字符串，作为事件的过滤器。如果进行了指定则函数只会返回名称符合此模式的事件。值可以为`nil`，此时事件名称不会被过滤。模式字符串的使用可参考`string.match`函数。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;...&amp;#039;&amp;#039;&amp;#039; - 任意数量的参数，顺序需要与目标[[Component/signals|信号]]所定义的相同。它们会被作为过滤器来筛选信号返回的额外参数，判断方式为是否完全相等。值可以为`nil`，这样将不会过滤此参数。&lt;br /&gt;
筛选样例： `touch`信号(在玩家点击2级或3级显示器时触发)带有如下参数：` screenX: number, screenY: number, playerName: string`(点击处的X、Y坐标，进行点击的玩家ID) 若要仅拉取玩家&amp;quot;Steve&amp;quot;的点击，你需要使用：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;`local _, x, y = event.pull(&amp;quot;touch&amp;quot;, nil, nil, &amp;quot;Steve&amp;quot;)`  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `event.pullFiltered([timeout: number], [filter: function]): string, ...`（自1.5.9起添加） 从队列中拉取并返回下一个可用事件，或者等待可用事件出现。支持以函数作为过滤器。 &amp;#039;&amp;#039;&amp;#039;timeout&amp;#039;&amp;#039;&amp;#039; - 若指定了值，则函数会至多等待此秒数。超时后仍未出现可用事件，则函数会返回`nil`。&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;filter&amp;#039;&amp;#039;&amp;#039; - 若指定了值，则此函数将会被作为事件的过滤器。让程序能够进行高级过滤。&lt;br /&gt;
&lt;br /&gt;
样例：&lt;br /&gt;
&lt;br /&gt;
```lua local allowedPlayers = {&amp;quot;Kubuxu&amp;quot;, &amp;quot;Sangar&amp;quot;, &amp;quot;Magik6k&amp;quot;, &amp;quot;Vexatos&amp;quot;} local function filter(name, ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;if name ~= &amp;quot;key_up&amp;quot; and name ~= &amp;quot;key_down&amp;quot; and name ~= &amp;quot;touch&amp;quot; then&lt;br /&gt;
  return false&lt;br /&gt;
end&lt;br /&gt;
local nick&lt;br /&gt;
if name == &amp;quot;touch&amp;quot; then&lt;br /&gt;
  nick = select(3, ...)&lt;br /&gt;
else&lt;br /&gt;
  nick = select(4, ...)&lt;br /&gt;
end&lt;br /&gt;
for _, allowed in ipairs(allowedPlayers) do&lt;br /&gt;
  if nick == allowed then&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
return false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local e = {event.pullFiltered(filter)} --程序将会不限时等待拉取key_up、key_down和click事件。过滤器会确保只拉取allowedPlayers表中的玩家触发的事件。 ```&lt;br /&gt;
&lt;br /&gt;
* `event.pullMultiple(...): ...`（自1.5.9起添加） `pullMultiple`函数可接收多个要拉取的事件名称作为参数，同时支持基本的过滤功能。&lt;br /&gt;
* `event.onError(message: any)` 全局的异常处理函数，用于处理事件回调函数抛出的错误。若有事件侦听器抛出异常，此函数将会进行处理，以避免其影响到不相关的代码（指仅是调用了`events.pull`函数触发函数执行的代码）。默认情况下，此函数会将报错信息记录到临时文件系统中的文件。 如果你想以其他方式处理事件报错，可以将此函数替换为自定义函数。&lt;br /&gt;
* `event.push(name: string[, ...])` 此函数仅仅为[[API/computer|computer.pushSignal]]的别名，并没有对参数进行任何修改。鉴于event(事件) API库中已经有了`event.pull`，添加此别名会更符合逻辑。&lt;br /&gt;
&lt;br /&gt;
== 中断 ==&lt;br /&gt;
&lt;br /&gt;
在OpenOS 1.6.4及更高版本，中断功能已经被删除。下列两个函数现在已经过时。&lt;br /&gt;
&lt;br /&gt;
* `event.shouldSoftInterrupt(): boolean`（自1.5.9起添加，在1.6.4被移除） - `event.shouldInterrupt(): boolean`（自1.5.9起添加，在1.6.4被移除）&lt;br /&gt;
&lt;br /&gt;
中断是一类用于关闭或停止进程的消息。在OpenOS中`computer.pullSignal()`函数及其封装会产生两种类型的事件。&lt;br /&gt;
&lt;br /&gt;
若`event.pull*()`函数在指定了过滤器但不指定超时时间的情况下执行，一定情况下意味着无限期执行。这两种事件非常有用。&lt;br /&gt;
&lt;br /&gt;
* 软中断是在按下`Ctrl+C`时产生的事件信号。信号包含两个参数，事件名称`&amp;quot;interrupted&amp;quot;`和电脑运行时间。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039; 硬中断在按下`Ctrl-Alt-C`时产生。它会通过抛出`&amp;quot;interrupted&amp;quot;`异常以强制退出`event.pull&amp;#039;&amp;#039;()`函数。&lt;br /&gt;
&lt;br /&gt;
== 简易事件处理样例 ==&lt;br /&gt;
&lt;br /&gt;
通常用户编写的脚本只会涉及一两个事件，不涉及其他事件的处理。建议将&amp;quot;interrupted&amp;quot;事件作为软件中断处理。&lt;br /&gt;
&lt;br /&gt;
```lua while true do&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;local id, _, x, y = event.pullMultiple(&amp;quot;touch&amp;quot;, &amp;quot;interrupted&amp;quot;)&lt;br /&gt;
if id == &amp;quot;interrupted&amp;quot; then&lt;br /&gt;
  print(&amp;quot;soft interrupt, closing&amp;quot;)&lt;br /&gt;
  break&lt;br /&gt;
elseif id == &amp;quot;touch&amp;quot; then&lt;br /&gt;
  print(&amp;quot;user clicked&amp;quot;, x, y)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end ```&lt;br /&gt;
&lt;br /&gt;
== 通用事件处理函数 ==&lt;br /&gt;
&lt;br /&gt;
此处提供了一个较好的通用事件处理函数。此样例的主要功能是以`event.pull()`函数返回的事件名称作为回调函数列表的键，用元方法来处理未定义事件。请注意`event.pull`函数会让程序进入等待状态，直到出现可用事件。&lt;br /&gt;
&lt;br /&gt;
```lua local event = require &amp;quot;event&amp;quot; --加载事件列表，将指向它们的指针存储到event变量中&lt;br /&gt;
&lt;br /&gt;
local char_space = string.byte(&amp;quot; &amp;quot;) --用数字代替空格字符 local running = true --存储状态的变量，便于循环停止执行&lt;br /&gt;
&lt;br /&gt;
function unknownEvent()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;--如果事件为无关事件，则不进行处理&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--存储所有事件处理函数的列表 --会返回占位伪函数unknownEvent，以防无法匹配 local myEventHandlers = setmetatable({}, { __index = function() return unknownEvent end })&lt;br /&gt;
&lt;br /&gt;
--简易按键处理函数样例，当用户按下空格键时将running变量设为false function myEventHandlers.key_up(adress, char, code, playerName)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;if (char == char_space) then&lt;br /&gt;
  running = false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--主事件处理函数，将事件ID(eventID)从其他参数中分离出来 function handleEvent(eventID, ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;if (eventID) then --如果一段时间内没有事件被拉取，值可能为nil&lt;br /&gt;
  myEventHandlers[eventID](...) --调用对应的事件处理函数，并传递剩下的所有参数&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--主事件拉取循环，处理所有事件。在没有任务时会等待。 while running do&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;handleEvent(event.pull()) --等待可用事件出现，然后进行处理&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end ```&lt;br /&gt;
&lt;br /&gt;
如果程序以驱动模式运作，你需要注册事件而不是拉取事件。你可以将所有事件注册到像上面样例一样的全局事件处理函数，也可以将每个事件注册到对应的处理函数。如果你希望上面的样例在后台运行，`while running do`循环需要替换为类似下面的代码：&lt;br /&gt;
&lt;br /&gt;
```lua event.listen(&amp;quot;key_up&amp;quot;, handleEvent) --注册handleEvent函数，使其在key_up事件发生时被调用，然后结束程序 ``` 也可以直接注册`myEventHandlers.key_up`，这样的话处理函数会额外收到一个参数（事件名称）作为第一个参数。&lt;br /&gt;
&lt;br /&gt;
== 目录 ==&lt;br /&gt;
&lt;br /&gt;
{{:API/contents/zh}}&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;OCDoc Import</name></author>
	</entry>
</feed>