键盘输入

Piglet提供了多种类型的键盘输入抽象:

  1. 适用于游戏控制的跨平台按键/释放事件

  2. 具有自动区域设置和平台处理功能的Unicode文本输入

  3. 常见文本编辑操作的跨平台检测

所有这些规定都有以下限制:

  1. 必须至少有一个侏儒 Window 可以保持键盘焦点的实例

  2. 使用以下样式创建的窗口无法保持键盘焦点:

如果您的项目需求超出了这些限制,您应该考虑替代方案。示例包括:

  • Python的内置功能 input() 功能

  • 这个 Textual 终端用户界面框架

键盘焦点约定

键盘焦点是用户键盘输入的发送位置。

桌面操作系统通常遵循以下约定:

  1. 只有一个窗口可以具有焦点

  2. 单击窗口即可获得焦点

  3. 具有焦点的窗口显示在所有其他窗口之上

  4. 具有焦点窗口具有独特的标题栏样式

  5. Windows可能会被夺走焦点

  6. Windows可以请求焦点

然而,以上内容并不能保证属实。

例如,pyglet允许您通过调用 Window.activate 。但是,操作系统可能不支持该功能。即使它确实支持它,操作系统也可能不仅拒绝,而且在不通知用户焦点被请求的情况下这样做。

偏离惯例的情况可能由于下列任何原因发生:

缘由

范例(S)

模式对话框

权限请求和错误通知

用户设置

窗口焦点设置为跟随鼠标

平台怪癖

具有多焦点模式的拆分屏幕实用程序和Linux窗口管理器

键盘事件

这个 on_key_press()on_key_release() 分别在按下或松开键盘上的任意键时激发事件。这些事件不受“键重复”的影响--一旦某个键被按下,该键就不再有任何事件,直到它被释放。

这两个事件都使用相同的参数进行了参数化::

def on_key_press(symbol, modifiers):
    pass

def on_key_release(symbol, modifiers):
    pass

定义的关键符号

这个 symbol 参数是一个表示“虚拟”密钥代码的整数。是的 not 对应于任何特定的编号方案;具体而言,符号是 not ASCII字符代码。

对于许多类型的键盘,pyglet都有独立于硬件和平台的按键符号。这些定义见 pyglet.window.key 作为常量。例如,拉丁文1字母表就是字母本身::

key.A
key.B
key.C
...

数字键带有下划线,以使其成为有效的标识符::

key._1
key._2
key._3
...

各种控制键和方向键由名称标识::

key.ENTER or key.RETURN
key.SPACE
key.BACKSPACE
key.DELETE
key.MINUS
key.EQUAL
key.BACKSLASH

key.LEFT
key.RIGHT
key.UP
key.DOWN
key.HOME
key.END
key.PAGEUP
key.PAGEDOWN

key.F1
key.F2
...

数字键盘上的按键有单独的符号::

key.NUM_1
key.NUM_2
...
key.NUM_EQUAL
key.NUM_DIVIDE
key.NUM_MULTIPLY
key.NUM_SUBTRACT
key.NUM_ADD
key.NUM_DECIMAL
key.NUM_ENTER

一些修改键的左侧和右侧有单独的符号(但是,它们不能在所有平台上都区分开来,包括Mac OSX):

key.LCTRL
key.RCTRL
key.LSHIFT
key.RSHIFT
...

关键符号独立于任何处于活动状态的修改器。例如,小写字母和大写字母都会生成 A 象征。数字键盘也是如此。

修饰词

在生成事件时处于活动状态的修饰符以按位方式组合,并在 modifiers 参数。中定义的修改量常量 pyglet.window.key 是::

MOD_SHIFT
MOD_CTRL
MOD_ALT         Not available on Mac OS X
MOD_WINDOWS     Available on Windows only
MOD_COMMAND     Available on Mac OS X only
MOD_OPTION      Available on Mac OS X only
MOD_CAPSLOCK
MOD_NUMLOCK
MOD_SCROLLLOCK
MOD_ACCEL       Equivalent to MOD_CTRL, or MOD_COMMAND on Mac OS X.

例如,要测试是否按住了Shift键::

if modifiers & MOD_SHIFT:
    pass

与相应的按键符号不同,无法确定是否按下了Left或Right修饰符(尽管您可以通过自己跟踪按键状态来模拟这种行为)。

用户定义的键符号

pyglet并没有为每一款键盘定义按键符号。例如,非拉丁语言将有许多键无法被pyglet识别(但是,它们的Unicode表示仍然有效,请参见 文本输入和运动事件 )。即使是英文键盘,制造商通常也会附加一些所谓的“OEM”键,比如“Media”、“Volume”或“Shopping”。

在这些情况下,Piglet将在运行时基于密钥的硬件扫描码创建密钥符号。这保证对于该型号的键盘是唯一的,但在具有相同标签键的其他键盘上可能不一致。

使用这些键的最佳方式是记录用户在提示后按下的内容,然后检查是否有相同的键符号。许多商业游戏都有类似的功能,允许玩家设置自己的密钥绑定。

记住密钥状态

KeyStateHandler 是一个存储当前键盘状态的便利类。实例可以被推送到任何窗口的事件处理程序堆栈上,然后使用键代码常量作为键进行查询::

from pyglet.window import key

window = pyglet.window.Window()
keys = key.KeyStateHandler()
window.push_handlers(keys)

# Check if the spacebar is currently pressed:
if keys[key.SPACE]:
    pass

文本输入和运动事件

除了单个按键事件外,pyglet还提供Unicode文本输入事件。这样做有几个好处:

  • 自动且正确地将特定于平台的修饰符和关键符号映射到Unicode字符

  • 按键重复会根据用户的操作系统首选项自动应用于文本输入。

  • 死键和合成键被自动解释为产生变音符号或组合字符。

  • 例如,键盘输入可以通过输入调色板来输入来自亚洲语言的字符。

  • 文本输入可以来自其他用户定义的来源,例如手写或语音识别。

实际的输入源(即,按下了哪些键或使用了什么输入法)应被考虑在应用程序的范围之外--操作系统提供必要的服务。

当文本输入到窗口中时, on_text() 事件被激发::

def on_text(text):
    pass

提供的唯一参数是Unicode字符串。尽管直接键盘输入通常只有一个字符长,但更复杂的输入方法(如输入调色板)可能会一次提供完整的单词或短语。

这与此有何不同 on_key_press()

  • 始终使用 on_text() 当您需要一系列击键中的字符串时,

  • 永远不要使用 on_text() 事件,例如在游戏中控制玩家的移动

运动项目

除了按键和输入新文本外,侏儒还支持常见的文本编辑动作:

  • 选择文本

  • 移动插入符号以响应非字符键

  • 删除、复制和粘贴文本

Puglet自动检测支持的运动的平台特定版本,并将其转换为跨平台 on_text_motion() 事件。这些事件旨在由 Caret 任何活动的 IncrementalTextLayout ,例如在 TextEntry 菲尔兹。

这个 motion 事件处理程序的参数将是在 pyglet.window.key 。下表列出了每个受支持平台上受支持的文本运动及其键盘映射。

常量

行为

Windows/Linux

Mac OS X

MOTION_UP

向上移动光标

向上

向上

MOTION_DOWN

将光标向下移动

降下来

降下来

MOTION_LEFT

将光标向左移动

左边

左边

MOTION_RIGHT

向右移动光标

正确的

正确的

MOTION_COPY

将当前选定内容复制到剪贴板

Ctrl+C

Command+C

MOTION_PASTE

将剪贴板内容粘贴到当前文档中

Ctrl+V

Command+V

MOTION_PREVIOUS_WORD

将光标移动到上一个单词

Ctrl+Left

Option+Left

MOTION_NEXT_WORD

将光标移动到下一个单词

Ctrl+右键

Option+Right

MOTION_BEGINNING_OF_LINE

将光标移动到当前行的开头

Command+Left

MOTION_END_OF_LINE

将光标移动到当前行的末尾

端部

Command+Right

MOTION_PREVIOUS_PAGE

移至上一页

翻页

翻页

MOTION_NEXT_PAGE

移至下一页

下页

下页

MOTION_BEGINNING_OF_FILE

移到文档的开头

Ctrl+Home键

MOTION_END_OF_FILE

移至文档末尾

Ctrl+End

端部

MOTION_BACKSPACE

删除前一个字符

退格键

退格键

MOTION_DELETE

删除下一个字符或当前字符

删除

删除

如果您认为pyglet需要添加对当前缺少的动议的支持,请跳至 添加新运动

由于插入符号和文本输入字段的互连方式,为单个项目自定义此行为目前很困难。但是,使用 on_key_press() 出于以下原因,仍应避免处理运动事件:

  • 支持的平台可以为不同的运动分配一个关键点。例如,在Windows上,使用Home键可以将光标移动到行的开头,但在Mac OS上,可以将光标移动到文档的开头。

  • 用户希望按住一个动作的键就可以重复释放它。例如,按住Backspace可删除多个字符。然而,只有一个 on_key_press() 事件会在每次按键时发生。

添加新运动

在添加新动议之前,请执行以下操作:

  1. 请参考上一节和每个平台的文档,以确保它是:

    1. 每个平台上都有一个通用的文本操作

    2. 尚未由Piglet实现

  2. 尝试在中查找相应的功能 Apple's NSTextView documentation

  3. 通过以下任一方式与维护人员讨论添加内容和任何剩余问题:

然后,一旦你准备好了:

  1. 将运动常量加到 pyglet.window.key

  2. 中为该常量添加一个条目 运动项目 部分

  3. 在中实现共享处理行为 on_text_motion()

  4. 实施Mac支持(通常是最令人困惑的步骤)

    1. 打开 pyglet/window/cocoa/pyglet_textview.py

    2. 实现相应的处理程序方法 PygletTextView_Implementation (侏儒的子类 NSTextView )

  5. 添加Windows键盘快捷键

    1. 打开 pyglet/window/win32/__init__.py

    2. 将键盘快捷键添加到 _motion_map 辞典

  6. 添加Linux键盘快捷键

    1. 打开 pyglet/window/xlib/__init__.py

    2. 将键盘快捷键添加到 _motion_map 辞典

如果可能的话,一定要在做公关之前测试一下你的改变!

如果您没有访问上述特定平台的权限,请在您的公关笔记中包含此信息。

键盘排他性

一些击键或组合键通常绕过应用程序,由操作系统处理。例如,Alt+Tab(Mac OS X上的Command+Tab)用于切换应用程序,而Mac OS X上的按键映射为Exposed。

您可以禁用这些热键,并使其行为类似于您的应用程序的普通击键。如果您正在开发不应该关闭的Kiosk应用程序,或者开发用户可能不小心按下这些键之一的游戏,这将非常有用。

若要启用此模式,请调用 Window.set_exclusive_keyboard 在它应该应用到的窗口上。在Mac OS X上,当专用键盘被激活时,停靠和菜单栏将滑出视线。

以下限制适用于Windows:

  • 只能禁用Alt+Tab

  • 用户仍可以通过以下方式切换应用程序:

    • Ctrl+Escape

    • Alt+Escape组合键

    • Windows键

    • Ctrl+Alt+Delete

以下限制适用于Mac OS X:

  • 电源键未禁用。

不建议在一般版本的应用程序或游戏中使用此函数,因为它违反了用户界面约定。