微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

一段时间后,pyglet 窗口与 schedule_once 挂起

如何解决一段时间后,pyglet 窗口与 schedule_once 挂起

就上下文而言,我尝试将 OpenAI 健身房与我编写的 pyglet 俄罗斯方块游戏结合使用。我面临的问题归结为下面的 MWE。

在始终相同的时间后,这里约 9 秒,窗口冻结,但来自 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 上,我无法准确重现您遇到的问题,但我确实注意到窗口在移动、单击、最小化/恢复时会冻结。问题似乎是您不分派这些类型的事件,因此它们将其置于事件队列中并阻止进一步绘制。一个快速的解决方法是在调用 self.window.dispatch_events 之后调用 self.window.clear()

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,height=wh)
        self.label = pyglet.text.Label('',anchor_y='center')
        
    def on_draw(self):
        self.clear()
        self.label.draw()

class Env:
    def __init__(self):
        self.window = Display(640,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()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。