在 Python pyglet 中按下按钮时做一些事情

Do something while the button is pressed in Python pyglet

@win.event
def on_key_press(key, modifiers):
    if key == pyglet.window.key.UP:
        print("UP")

这个函数只打印一次 UP,但我想在按住 UP 按钮的同时打印 UP。

您需要在 on_key_press 之外进行此检查。
由于该函数是一次性函数,仅在触发按键 DOWN 事件时调用。并且该触发器仅从操作系统执行一次。

因此您需要保存 DOWN 状态 (on_key_press) 并将按下的键保存在某个变量中 (下面,我称之为self.keys.
随后,您还需要处理任何 RELEASE 事件,在我下面的示例中,这些事件是在 on_key_release.

中完成的

以下是如何将它们结合在一起的:

from pyglet import *
from pyglet.gl import *

key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
        super(main, self).__init__(width, height, *args, **kwargs)

        self.keys = {}

        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_key_release(self, symbol, modifiers):
        try:
            del self.keys[symbol]
        except:
            pass

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE: # [ESC]
            self.alive = 0

        self.keys[symbol] = True

    def render(self):
        self.clear()

        ## Add stuff you want to render here.
        ## Preferably in the form of a batch.

        self.flip()

    def run(self):
        while self.alive == 1:
            # -----------> This is key <----------
            # This is what replaces pyglet.app.run()
            # but is required for the GUI to not freeze
            #
            event = self.dispatch_events()

            if key.UP in self.keys:
                print('Still holding UP')
            self.render()

if __name__ == '__main__':
    x = main()
    x.run()

pyglet 似乎为此用例引入了事件处理程序:https://pyglet.readthedocs.io/en/latest/programming_guide/keyboard.html#remembering-key-state。文档中的代码示例:

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.window.Window 继承子类,这是一种可能的方法:

import pyglet
from pyglet.window import key

class MyWindow(pyglet.window.Window):

    def __init__(self):
        super(MyWindow, self).__init__()

        self.key_handler = key.KeyStateHandler()
        self.push_handlers(self.key_handler)

    def on_draw(self):
        self.clear()

    def update(self, _):
        if self.key_handler[key.UP]:
            print('UP key pressed')

if __name__ == '__main__':
    mygame = MyWindow()
    pyglet.clock.schedule_interval(mygame.update, 1/60)
    pyglet.app.run()