Search code examples
pythonpython-3.xpyglet

Python Pyglet mouse events don't call on_draw() nor make changes in window


for some reason, any mouse event that happens with my program doesn't make the image in the window disappear nor reappear, although my on_key_press() function works.

I've tried state flags and declaring a new image resource, but it doesn't change anything in the window.

Is there a way to make this work? Should I revert to a previous pyglet version? If so, which version?

Here's my code of the program; it runs with the test image visible, and every time a key is pressed or the mouse is clicked, the image will disappear or reappear:

import pyglet

window = pyglet.window.Window()

image = pyglet.resource.image('test.png')
image.anchor_x = image.width // 2
image.anchor_y = image.height // 2

state = True


@window.event
def on_draw():
    print('on_draw() called')
    window.clear()
    if state:
        image.blit(window.width // 2, window.height // 2)


@window.event
def on_mouse_press(x, y, button, modifiers):
    global state, image
    if button == pyglet.window.mouse.LEFT:
        print('mouse press')
        if state:
            state = False
        else:
            state = True


@window.event
def on_key_press(symbol, modifiers):
    global state
    print('key press')
    if state:
        state = False
    else:
        state = True


pyglet.app.run()

Thanks!

Edit: My python version is 3.7.2 and my pyglet version is 1.4.7, and I use pycharm, if the fact seems to factor in...


Solution

  • It seems to be an issue with the decorator function.

    As Torxed suggested, instead of decorating on_mouse_press, replace the window object's on_mouse_press function with your own declaration of that function:

    import pyglet
    
    
    image = pyglet.resource.image('test.png')
    image.anchor_x = image.width // 2
    image.anchor_y = image.height // 2
    
    state = True
    
    
    def on_draw():
        print('on_draw() called')
        window.clear()
        if state:
            image.blit(window.width // 2, window.height // 2)
    
    
    def on_mouse_press(x, y, button, modifiers):
        global state
        print('mouse pressed')
        if state:
            state = False
        else:
            state = True
    
    
    window = pyglet.window.Window()
    window.on_draw = on_draw
    window.on_mouse_press = on_mouse_press
    
    pyglet.app.run()
    
    

    Otherwise, create a subclass of the Window object and override the on_mouse_press function with your own declaration:

    import pyglet
    
    class Window(pyglet.window.Window):
        def __init__(self, *args, **kwargs):
            super().__init__(800, 600)
            self.image = pyglet.resource.image('test.png')
    
            self.image = pyglet.resource.image('test.png')
            self.image.anchor_x = self.image.width // 2
            self.image.anchor_y = self.image.height // 2
    
            self.state = True
    
        def on_draw(self):
            print('on_draw() called')
            window.clear()
            if self.state:
                self.image.blit(self.width // 2, self.height // 2)
    
        def on_mouse_press(self, x, y, button, modifiers):
            print('mouse pressed')
            if self.state:
                self.state = False
            else:
                self.state = True
    
    
    window = Window()
    
    pyglet.app.run()