user2879397
user2879397

Reputation: 3

pyglet on_draw event stops until mouse moves

I'm trying to write my first pyglet animation and I ran into a problem.

I have an update function called from the on_draw function. It does what it should do, but it stops at random places down the loop. If I start moving the mouse it continues going down the loop.

I saw there is a question made here in 2011 about the same problem but with no relevant answer: (pyglet on_draw event occurs only when mouse moves)

To work I need to keep calling the update function inside the on_draw.

This is the code for both functions:

def update(zd):
    stripe.y += zd[0]
    stripe._set_rotation(zd[0])

@window.event
def on_draw():
    window.clear()
    window.clear()
    batch.draw()
    try:
        update(next(calc))
    except:
        pass

I get the zd to the update from a big loop with a lot of calculations in the calc function.

Upvotes: 0

Views: 935

Answers (1)

Torxed
Torxed

Reputation: 23480

Here, try this code instead:

import pyglet
from pyglet.gl import *
from math import radians, cos, sin, degrees, atan2
from time import time

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_LINE_SMOOTH)
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE)
pyglet.options['audio'] = ('alsa', 'openal', 'silent')
key = pyglet.window.key

class GUI(pyglet.window.Window):
    def __init__(self):
        super(GUI, self).__init__(640,340, caption='My app')
        self.alive = True
        self.keys_down = {}

        imgTexture = pyglet.image.load('/path/to/image.png')
        self.myImage = pyglet.sprite.Sprite(imgTexture)
        self.myImage.x, self.myImage.y = 10, 50 # x,y from bottom left corner

    def render(self, *args):
        pyglet.gl.glClearColor(1, 1, 1, 1)
        self.clear()
        # .. This is where you draw your objects, for instance
        self.myImage.draw()
        self.flip()

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = False

    def on_key_press(self, symbol, modkey):
        self.keys_down[symbol] = time()

    def on_key_release(self, symbol, modkey):
        if symbol in self.keys_down:
            del(self.keys_down[symbol])

    def on_mouse_release(self, x, y, button, modifiers):
        pass

    def on_mouse_press(self, x, y, button, modifiers):
        print(button,'pressed',(x,y))


    def on_mouse_motion(self, x, y, dx, dy):
        pass

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        pass

    def run(self):
        while self.alive:
            event = self.dispatch_events()

            for symbol in self.keys_down:
                if symbol == key.ESCAPE:
                    self.alive = None
                    break
                elif symbol == key.LEFT:
                    pass #Arrowkey Left
                elif symbol == key.RIGHT:
                    pass #Arrowkey Right
                elif symbol == key.UP:
                    pass #Arrowkey Up
                elif symbol == key.DOWN:
                    pass #Arrowkey Down
                elif symbol == 65515:
                    pass # Win key
                else:
                    print(symbol)
            self.render()


if __name__ == '__main__':
    x = GUI()
    pyglet.clock.set_fps_limit(120)
    x.run()

Note that on_draw() is not really called ever in this code.
In the traditional pyglet code on_draw() is only called whenever a event exists, normally you trigger these with a timer or otherwise scheduled event.. Moving the mouse is one such event.

This is a manual override of the traditional app.run() that you're used to.
So the two main functions here are:

  1. event = self.dispatch_events()
  2. self.render()

The first fetches any events from pyglet effectively releasing any locks because even empty events must be fetched. The second is the rendering functions which is what on_draw() normally does, except we can now call it all the time (or whenever we want).

I'm no expert but this works for 99% of any GUI making you'll ever encounter, as long as you're not going to do massive 3D games, this will do the job for you.

Upvotes: 1

Related Questions