Explicit event to redraw a window

2,225 views
Skip to first unread message

anatoly techtonik

unread,
Jul 23, 2012, 6:46:59 AM7/23/12
to pyglet...@googlegroups.com
Hi,

What is the correct way to initiate window redraw?

Nathan

unread,
Jul 23, 2012, 12:27:50 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 4:46 AM, anatoly techtonik <tech...@gmail.com> wrote:
> Hi,
>
> What is the correct way to initiate window redraw?

If I understand correctly (correct me if I'm wrong, people), every
Window's on_draw() function is called once each time the event "idle"
loop runs.

You could:

1) Call the window's on_draw() method manually if you want it called
_more_ often.
2) Override the default idle policy of the event loop by subclassing
it if you don't want it called exactly once per window per event loop.
See [a].

[a] http://www.pyglet.org/doc/programming_guide/customising_the_event_loop.html#id108

~ Nathan

anatoly techtonik

unread,
Jul 23, 2012, 12:53:54 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 7:27 PM, Nathan <nathan...@gmail.com> wrote:
> On Mon, Jul 23, 2012 at 4:46 AM, anatoly techtonik <tech...@gmail.com> wrote:
>> Hi,
>>
>> What is the correct way to initiate window redraw?
>
> If I understand correctly (correct me if I'm wrong, people), every
> Window's on_draw() function is called once each time the event "idle"
> loop runs.

I've started with Hello World, and on Linux this means its window is
redrawn only once on startup and then each time a key is pressed.

http://www.pyglet.org/doc/programming_guide/hello_world.html

> You could:
>
> 1) Call the window's on_draw() method manually if you want it called
> _more_ often.

If I place this into on_draw() it will create call stack overflow and
"Hello, World" will crash.

> 2) Override the default idle policy of the event loop by subclassing
> it if you don't want it called exactly once per window per event loop.
> See [a].
>
> [a] http://www.pyglet.org/doc/programming_guide/customising_the_event_loop.html#id108

Sounds complicated. It will be enough for me to send some event at the
end of on_draw to kick the loop again. I don't know how to do this
properly. Sending keyboard events doesn't sound right.
--
anatoly t.

Nathan

unread,
Jul 23, 2012, 1:03:53 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 10:53 AM, anatoly techtonik <tech...@gmail.com> wrote:
> On Mon, Jul 23, 2012 at 7:27 PM, Nathan <nathan...@gmail.com> wrote:
>> On Mon, Jul 23, 2012 at 4:46 AM, anatoly techtonik <tech...@gmail.com> wrote:
>>> Hi,
>>>
>>> What is the correct way to initiate window redraw?
>>
>> If I understand correctly (correct me if I'm wrong, people), every
>> Window's on_draw() function is called once each time the event "idle"
>> loop runs.
>
> I've started with Hello World, and on Linux this means its window is
> redrawn only once on startup and then each time a key is pressed.

That doesn't sound right. Can you post the entire hello world source
code you have?

> http://www.pyglet.org/doc/programming_guide/hello_world.html
>
>> You could:
>>
>> 1) Call the window's on_draw() method manually if you want it called
>> _more_ often.
>
> If I place this into on_draw() it will create call stack overflow and
> "Hello, World" will crash.

Well, right, you shouldn't call it from within itself. It'll just
recurse until it crashes if you do that. I meant you could call it
from pretty much any other code that happens to be running during a
loop. But it sounds like there's something wrong with your basic
Hello World example, so I don't think you're looking for this level of
a solution.

>> 2) Override the default idle policy of the event loop by subclassing
>> it if you don't want it called exactly once per window per event loop.
>> See [a].
>>
>> [a] http://www.pyglet.org/doc/programming_guide/customising_the_event_loop.html#id108
>
> Sounds complicated. It will be enough for me to send some event at the
> end of on_draw to kick the loop again. I don't know how to do this
> properly. Sending keyboard events doesn't sound right.

Right. Lets get the basic hello world working for you.

~ Nathan

anatoly techtonik

unread,
Jul 23, 2012, 1:11:54 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 8:03 PM, Nathan <nathan...@gmail.com> wrote:
> On Mon, Jul 23, 2012 at 10:53 AM, anatoly techtonik <tech...@gmail.com> wrote:
>> On Mon, Jul 23, 2012 at 7:27 PM, Nathan <nathan...@gmail.com> wrote:
>>> On Mon, Jul 23, 2012 at 4:46 AM, anatoly techtonik <tech...@gmail.com> wrote:
>>>> Hi,
>>>>
>>>> What is the correct way to initiate window redraw?
>>>
>>> If I understand correctly (correct me if I'm wrong, people), every
>>> Window's on_draw() function is called once each time the event "idle"
>>> loop runs.
>>
>> I've started with Hello World, and on Linux this means its window is
>> redrawn only once on startup and then each time a key is pressed.
>
> That doesn't sound right. Can you post the entire hello world source
> code you have?

---[ fps.py ]---
import pyglet

window = pyglet.window.Window()

counter = 0
@window.event
def on_draw():
global counter
counter += 1
window.clear()
label = pyglet.text.Label('Count: %s' % counter,
font_name='Times New Roman',
font_size=36,
x=window.width//2, y=window.height//2,
anchor_x='center', anchor_y='center')
label.draw()

pyglet.app.run()

---[ /fps.py ]---

Tristam MacDonald

unread,
Jul 23, 2012, 1:31:03 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 6:46 AM, anatoly techtonik <tech...@gmail.com> wrote:
Hi,

What is the correct way to initiate window redraw?

What's wrong with scheduling an update function? IIRC, that should trigger a redraw whenever it occurs.

def update(dt):
    pass 

pyglet.clock.schedule_interval(update, 1/60.0)

-- 
Tristam MacDonald

anatoly techtonik

unread,
Jul 23, 2012, 1:49:58 PM7/23/12
to pyglet...@googlegroups.com
On Mon, Jul 23, 2012 at 8:31 PM, Tristam MacDonald <swift...@gmail.com> wrote:
> On Mon, Jul 23, 2012 at 6:46 AM, anatoly techtonik <tech...@gmail.com>
> wrote:
>>
>> Hi,
>>
>> What is the correct way to initiate window redraw?
>
>
> What's wrong with scheduling an update function? IIRC, that should trigger a
> redraw whenever it occurs.
>
> def update(dt):
> pass
>
> pyglet.clock.schedule_interval(update, 1/60.0)

Thanks. Surprisingly, an empty update() call kicks event loop as
expected. I want to measure maximum FPS possible on 100% CPU load, so
a 1/10000 value looks good for my case. But for the clarity I'd still
prefer to kick event loop explicitly. Unfortunately, Google Code
Hosting is down at the moment and don't allow me to browse the sources
to see how is it implemented.
--
anatoly t.

Tristam MacDonald

unread,
Jul 23, 2012, 2:11:28 PM7/23/12
to pyglet...@googlegroups.com
Ok, so it's not really possible to do so unless you implement your own event loop.

The default event loop redraws every window for which window.invalid == True (which it is by default), every time through the event loop.

If you want to redraw as fast as possible, you do exactly as you did (schedule a high frequency update function), because each time that is called the event loop is run, and redraw will happen.

anatoly techtonik

unread,
Jul 23, 2012, 2:42:01 PM7/23/12
to pyglet...@googlegroups.com
I'm looking at the pyglet.clock code from
pyglet.clock.schedule_intervalpyglet.clock.schedule_interval
entrypoint and can't find a place where an event loop iteration is
triggered. There is a Clock.call_scheduled_functions, but it is still
unclear what causes it to run, how does it interacts with the event
loop and how come that the on_draw() is called as a result?

http://code.google.com/p/pyglet/source/browse/pyglet/clock.py
--
anatoly t.

Tristam MacDonald

unread,
Jul 23, 2012, 2:48:18 PM7/23/12
to pyglet...@googlegroups.com
You need to look at the app classes for each platform - pretty sure that hook happens in the app, not the clock.

Peter Enerccio

unread,
Jul 23, 2012, 11:05:22 PM7/23/12
to pyglet...@googlegroups.com
Or maybe you can call on_draw() along with flipping display in on_draw, if you prevent recursion by using some sentinel?

sentinel = False;
def on_draw():
    ....
    if not sentinel:
        sentinel = True
        on_draw()
        flip()
    sentinel = False
   

2012/7/23 Tristam MacDonald <swift...@gmail.com>
--
You received this message because you are subscribed to the Google Groups "pyglet-users" group.
To post to this group, send email to pyglet...@googlegroups.com.
To unsubscribe from this group, send email to pyglet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pyglet-users?hl=en.



--
Bc. Peter Vaňušanik
http://www.bishojo.tk

Peter Enerccio

unread,
Jul 23, 2012, 11:07:40 PM7/23/12
to pyglet...@googlegroups.com
Although, ultimately, I would skip event loop altogether and just use manual event loop, since idling in games and stuff is not worth. See more: http://www.pyglet.org/doc/programming_guide/dispatching_events_manually.html

2012/7/24 Peter Enerccio <ener...@gmail.com>
Reply all
Reply to author
Forward
0 new messages