Update and On_Draw Pyglet in Thread

2019-08-20 06:45发布

问题:

I wanted to ask, is it possible to put the Update and On_Draw functions of a Pyglet class created by the user in a thread? Let me explain. I have the class of my app of Pyglet, in which I need some functions (always of the same class) that work simultaneously with the Update and On_Draw functions. Now, I've been looking around and the only things I've found is inserting the entire Pyglet app into a main thread, but doing so would give problems to the Pyglet itself. I just need to have those two functions in one main thread and the other functions in secondary threads. It's possible to do it?

EDIT:

With a few tries, since this is the first time I've used threads, I've managed to put together a script that works.

from pyglet.gl import *
from pyglet.window import FPSDisplay
import threading, time, os

FPS = 120.0

class test(pyglet.window.Window):

    loop = True
    th = True
    load = 10

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__video_set()
        self.label = pyglet.text.Label(('LOADING: '+str((self.load-10)//10)+"%"), font_name='Times New Roman', font_size=36)
        self.label.x = self.width // 2
        self.label.y = self.height // 2 + 200
        self.thread = threading.Thread(target=self.loader)
        self.thread.start()

    def loader(self):
        time.sleep(1)
        while self.loop is True:
            time.sleep(0.05)
            if self.load >= 1010:
                self.loop = False
            else:
                self.load += 1

    def on_draw(self):
        self.clear()
        self.bar = pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (10, 250, int(self.load), 250)))
        self.bar = pyglet.gl.glLineWidth(20)
        if self.load >= 15:
            self.label.draw()

    def update(self, dt):
        if self.load >= 1010:
            self.label.text = ("LOADING COMPLETE")
        else:
            self.label.text = ("LOADING: "+str((self.load-10)//10)+"%")

    def on_close(self):
        self.close()
        os._exit(0)

    def __video_set(self):
        self.__platform = pyglet.window.get_platform()
        self.__default_display = self.__platform.get_default_display()
        self.__default_screen = self.__default_display.get_default_screen()
        self.__default_dimension_screen = 1024, 576

        self.set_size(self.__default_dimension_screen[0], self.__default_dimension_screen[1])
        self.location = self.__default_screen.width // 2 - self.__default_dimension_screen[0] // 2, self.__default_screen.height // 2 - self.__default_dimension_screen[1] // 2
        self.set_location(self.location[0], self.location[1])

if __name__ == "__main__":
    ts = test()
    pyglet.clock.schedule_interval(ts.update, 1 / FPS)
    pyglet.app.run()

This script simulates an initial load, with a loading bar and a percentage that shows loading. A thread is opened in which there is a while cycle which simulates the loading and every time it cycles, it modifies the self.load variable. Since this is the first time I get my hands on the threads, is the work I've done right? Also, I would like to ask, in the thread function, I was forced to insert two time.sleep. This is because no matter where I put it, if in the __init__ function, or in the update or other function, the thread was too fast and ended either before the window was created, or the loading bar went from 0 to 100 in less than a second. Is there a solution without having to use time.sleep?