一段时间后,pyglet windows 与 schedule_once 挂起
pyglet windows hang with schedule_once after some time
对于上下文,我正在尝试将 OpenAI gym 与我编写的 pyglet 俄罗斯方块游戏一起使用。我面临的问题归结为下面的 MWE。
经过始终相同的时间后,此处为约 9 秒,window 冻结,但来自 toto 函数和渲染函数的打印仍在打印。
我快要疯了。 Pyglet 看起来不错,但我几乎找不到任何文档,而官方文档几乎没有帮助。
如果我用带有 on_draw() 函数的更简单的代码做同样的事情,没问题,但我需要这个用于健身房部分。
谢谢
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.clear()
label = pyglet.text.Label('iter {:f}'.format(i),
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
label.draw()
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto(dt):
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
pyglet.clock.schedule_once(toto, 1)
pyglet.app.run()
至少在 Windows 上,我无法完全重现您遇到的问题,但我确实注意到 window 在移动、单击时冻结,minimized/restored.问题似乎是您不发送此类事件,因此它们将其放在事件队列中并阻止进一步绘制。快速修复是在调用 self.window.clear()
.
之后调用 self.window.dispatch_events
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.clear()
self.window.dispatch_events()
label = pyglet.text.Label('iter {:f}'.format(i),
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
label.draw()
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto(dt):
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
pyglet.clock.schedule_once(toto, 1)
pyglet.app.run()
您在这里似乎没有充分利用默认的 Pyglet 事件循环,因此您可能只想编写自己的事件循环。这是您可以做到这一点的一种方法。
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
self.label = pyglet.text.Label('',
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
def on_draw(self):
self.clear()
self.label.draw()
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.label.text = "iter {:f}".format(i)
self.window.switch_to()
self.window.dispatch_events()
self.window.dispatch_event('on_draw')
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto():
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
toto()
对于上下文,我正在尝试将 OpenAI gym 与我编写的 pyglet 俄罗斯方块游戏一起使用。我面临的问题归结为下面的 MWE。
经过始终相同的时间后,此处为约 9 秒,window 冻结,但来自 toto 函数和渲染函数的打印仍在打印。 我快要疯了。 Pyglet 看起来不错,但我几乎找不到任何文档,而官方文档几乎没有帮助。 如果我用带有 on_draw() 函数的更简单的代码做同样的事情,没问题,但我需要这个用于健身房部分。
谢谢
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.clear()
label = pyglet.text.Label('iter {:f}'.format(i),
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
label.draw()
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto(dt):
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
pyglet.clock.schedule_once(toto, 1)
pyglet.app.run()
至少在 Windows 上,我无法完全重现您遇到的问题,但我确实注意到 window 在移动、单击时冻结,minimized/restored.问题似乎是您不发送此类事件,因此它们将其放在事件队列中并阻止进一步绘制。快速修复是在调用 self.window.clear()
.
self.window.dispatch_events
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.clear()
self.window.dispatch_events()
label = pyglet.text.Label('iter {:f}'.format(i),
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
label.draw()
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto(dt):
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
pyglet.clock.schedule_once(toto, 1)
pyglet.app.run()
您在这里似乎没有充分利用默认的 Pyglet 事件循环,因此您可能只想编写自己的事件循环。这是您可以做到这一点的一种方法。
import pyglet
import time
class Display(pyglet.window.Window):
def __init__(self, ww, wh):
super().__init__(width=ww, height=wh)
self.label = pyglet.text.Label('',
font_size=16,
x=300,
y=200,
anchor_x='left', anchor_y='center')
def on_draw(self):
self.clear()
self.label.draw()
class Env:
def __init__(self):
self.window = Display(640, 480)
def render(self, i):
self.window.label.text = "iter {:f}".format(i)
self.window.switch_to()
self.window.dispatch_events()
self.window.dispatch_event('on_draw')
print('iter {:f}'.format(i))
self.window.flip()
env = Env()
def toto():
for t in range(300):
time.sleep(0.5)
print("toto {:d}".format(t))
env.render(t)
print("done")
toto()