简单的小部件和图形用户界面

这个 pyglet.gui 模块提供了一系列可用于向游戏或应用程序添加用户界面元素的小部件。选择有限,但应涵盖最常见的用例。例如:游戏中的配置屏幕,或可视化程序的一组工具栏按钮。

Widget是从其他高级侏儒对象内部构造的,因此在设计上相当简单。他们应该很好地融入任何侏儒项目。例如,小部件是从窗口接收键盘和鼠标事件的事件处理程序。然后,它们可以依次调度自己的定制事件,因为它们是子类 EventDispatcher 。小部件可以使用Batch和Group,类似于其他侏儒对象,以允许 批处理渲染

在进一步阅读之前,了解事件处理和分派在pyglet中是如何工作的很重要。如果您还没有这样做,建议您首先通读 事件调度和处理 部分的文档。小部件本质上与输入事件关联非常紧密,因此这对于完全掌握它们的用法是必要的。

示例代码可以在pyglet源代码库的‘Examples/gui/widgets.py’中找到。

创建小工具

包括的小部件有 PushButtonToggleButtonSlider ,以及 TextEntry 。它们各自有不同的参数,将在API文档中显示。在我们的示例中,我们将创建一个‘Push Button’小部件,它要求您至少提供两个图像。这两个图像将在视觉上表示按钮的“按下”和“按下”状态。这个小部件也可以获取一个可选的‘hover’图像,但我们现在跳过这一步::

pressed_img = pyglet.resource.image("button_pressed.png")
depressed_img = pyglet.resource.image("button_depressed.png")

pushbutton = pyglet.gui.PushButton(x=100, y=300, pressed=pressed_img, depressed=depressed_img, batch=batch)

我们现在有了一个按钮小部件,但它还不会做任何事情。但是,如果将其作为 Batch 如上所示。为了让小部件对鼠标做出反应,我们需要将其设置为处理由窗口::

my_window.push_handlers(pushbutton)

现在,当您单击该小部件时,它的外观应该会更改。它将在提供的图像(按下和按下状态)之间切换。你也可以尝试添加“悬停”图像,以获得更多的视觉反馈。

现在我们的小部件正在接收事件,我们现在可以获取生成的事件 _by_ 小工具。在本例中,按钮小部件调度两个事件:‘ON_PRESSED’和‘ON_RELEASE’。要将这些连接起来,我们只需为它们设置处理程序::

def my_on_press_handler():
    print("Button Pressed!")

def my_on_release_handler():
    print("Button Released...")

pushbutton.set_handler('on_press', my_on_press_handler)
pushbutton.set_handler('on_release', my_on_release_handler)

如果我们尝试此代码,每当我们按下并释放按钮时,我们应该会看到消息打印到控制台。现在,您有了一种让小部件与项目中的代码交互的方法。

其他小部件也以类似的方式使用,但根据它们的性质有不同的论据。请看一下每个应用程序的API文档,并查看源代码存储库中的示例。

框对象

Piglet还提供了可选的 Frame 对象。如果一次只需要几个小部件,那么可以忽略此对象。然而,如果您同时使用几十个小部件,您可能会发现让每个小部件同时接收窗口事件是非常浪费的。这就是框架可能有用的地方。从本质上讲,它充当窗口事件和窗口小部件之间的“中间人”。框架实现了一个简单的2D空间散列,它只将窗口事件传递给那些实际位于鼠标指针附近的小部件。这对于通常关心鼠标点击和键盘键的小部件来说工作得很好,但对于拖放类型事件有一些限制(稍后将详细介绍)。

在没有框架的情况下,小部件的一般用法是:

  1. 创建一个或多个Widget实例。

  2. 将Wiget作为事件处理程序推入您的窗口。

  3. 所有窗口小部件接收所有窗口事件。

如果引入帧,则会发生以下情况:

  1. 创建单个帧实例。

  2. 将框架设置为窗口事件的处理程序。

  3. 创建一个或多个Widget实例。

  4. 将您的小部件实例添加到框架中。

  5. 只有鼠标指针附近的窗口小部件才会接收窗口事件。

这在大多数情况下工作得很好,但也有一些限制。例如,在使用TextEntry小部件时,如果您使用单击并拖动来选择文本,则小部件可能会变得没有响应,但您的鼠标指针距离小部件足够远。因此,框架可能不适合使用。

框架的概念可能会在未来的版本中得到进一步的发展,但目前它的服务有限但有用。

自定义小部件

对于对创建自己的自定义小部件感兴趣的用户, WidgetBase 基类可用于子类化。这个基类预定义了大多数相关的窗口事件,可以作为处理程序进行推送。然后,自定义子类可以重写它们需要的任何鼠标或键盘事件,具体取决于应用程序。还提供了一些附加的帮助器属性。

建议您浏览一下这个小工具的源代码,以便更好地理解它在实践中的样子。因为小部件是由其他高级的侏儒对象组成的,所以您可能会发现它并不是特别复杂。例如,按钮Widget只有不到100行代码。这可能是为您的特定用例设计定制小部件的一个很好的起点。

这一部分可能会在将来的版本中进一步扩展。