Search code examples
pyglet

pyglet on_draw event occurs only when mouse moves


I have a strange problem. When pyglet app starts it just draws 1-2 frames then freezes. on_draw event just stops occuring. But everytime I move mouse or press keys, on_draw event dispatches as well. In short I have to move mouse to make my pyglet application basically work.

This is actually happens in Windows. In Ubuntu with compiz I've to move mouse just once then application starts working normally.

This is my code example:

#!/usr/bin/env python

import pyglet

win = pyglet.window.Window(width=800, height=600)
label = pyglet.text.Label('Abc', x=5, y=5)

@win.event
def on_draw():
    win.clear()
    label.x += 1
    label.draw()

pyglet.app.run()

Here's a video explaining things.


Solution

  • I came across this last night while trying to figure out the same problem. I figured out what causes this.

    I had used a decorator and put my updates in the on_draw method, and it would run okay for a little while, then it would freeze, only to start working again when I moved the mouse or hit the keyboard. I tried all sorts of tricks to figure it out, I finally thought that maybe things were just running too fast, and that putting them in a batch and letting pyglet decide when to update them would be better. It worked.

    I also scheduled things so that they would run about twice as fast as my refresh rate, but not so fast it would bog anything down. This is more than enough for smooth animations.

    needles_list = [gauges.speedometer.Needle(speedometer_data, needle, batch=batch, group=needles),
                    gauges.tachometer.Needle(tachometer_data, needle, batch=batch, group=needles)]
    
    def update(dt):
    for needle in needles_list:
        needle.update(dt)
    
    pyglet.clock.schedule_interval(update, 1/120.0)
    

    gauges.speedometer.Needle and gauges.tachometer.Needle are subclasses of pyglet.sprite.Sprite, and I wrote an update method for each of them. I then called their draw method in on_draw as normal.

    @window.event()
    def on_draw():
        window.clear()
        batch.draw()
    

    I know this question has been up for a while, and the asker may have given up already, but hopefully it will help anyone else that's having this problem.