Как обновить метку в Pyglet без ошибки недопустимой операции? - PullRequest
0 голосов
/ 10 июля 2020

У меня есть программа-пиглет, которая запускает GUI в одном потоке и получает сообщение из другого потока. Он должен обновить GUI на основе этого сообщения. Проблема, однако, в том, что всякий раз, когда я go обновляю элемент GUI, я получаю такое сообщение об ошибке:

Traceback (most recent call last):
  File --- line 40, in run
    pub.sendMessage("update", msg="Banana")
  File --- line 77, in updateDisplay
    self.label.text = msg
  File "---\pyglet\text\__init__.py", line 289, in text
    self.document.text = text
  File "---\pyglet\text\document.py", line 294, in text
    self.insert_text(0, text)
  File "---\pyglet\text\document.py", line 425, in insert_text
    self.dispatch_event('on_insert_text', start, text)
  File "---\pyglet\event.py", line 408, in dispatch_event
    if handler(*args):
  File "---\pyglet\text\layout.py", line 1045, in on_insert_text
    self._init_document()
  File "---\pyglet\text\layout.py", line 1034, in _init_document
    self._update()
  File "---\pyglet\text\layout.py", line 957, in _update
    lines = self._get_lines()
  File "---\pyglet\text\layout.py", line 933, in _get_lines
    glyphs = self._get_glyphs()
  ...
  File "---\pyglet\font\base.py", line 246, in fit
    region.blit_into(image, 0, 0, 0)
  File "---\pyglet\image\__init__.py", line 1730, in blit_into
    self.owner.blit_into(source, x + self.x, y + self.y, z + self.z)
  File "---\pyglet\image\__init__.py", line 1622, in blit_into
    glBindTexture(self.target, self.id)
  File "---\pyglet\gl\lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'invalid operation'

Оперативная ошибка pyglet.gl.lib.GLException: b'invalid operation '

Я знаю, что self.label.text = Y работает, потому что он обновляет текст, если я помещаю его в функцию init(). Однако попытка выполнить какое-либо обновление с помощью функции update_display (см. Код ниже) вызывает эту ошибку. Я знаю, что функция вызывается правильно, потому что она успешно выводит сообщение на консоль, но ломается в строке элемента обновления. Я пробовал другие элементы, кроме label, и это то же самое.

Я понятия не имею, почему он выдает эту ошибку или как ее решить. Есть идеи?

Мой код:

import pyglet
from threading import Thread
from random import choice
from time import sleep
from pubsub import pub

RUN = True


class MessageThread(Thread):

    def __init__(self):
        """Init Thread Class."""
        
        Thread.__init__(self)
        self.start()    # start the thread

    def run(self):
        """Run Thread."""
        
        array = [0, 1, 2]
            
        while True:
    
            if RUN == False:
                print("End runner")
                break
            
            value = choice(array)
            sleep(1)
                
            if value == 0:
                print("event", value, ": Apple", flush=True)
                pub.sendMessage("update", msg="Apple")

            elif value == 1:
                print("event", value, ": Banana", flush=True)
                pub.sendMessage("update", msg="Banana")
                
            else:
                print("event", value, ": Carrot", flush=True)
                pub.sendMessage("update", msg="Carrot")

        
class MyGUI(pyglet.window.Window):
 
    # Note: With this structure, there is no "self.app", you just use
    # self. This structure allows onDraw() to be called.
    
    def __init__(self):
        
        super(MyGUI, self).__init__(width=600,height=650,resizable=True) 
        
        self.label = pyglet.text.Label('Waiting...',
                          font_name='Times New Roman',
                          font_size=36,
                          x=self.width/2, y=self.height - 36,
                          anchor_x='center', anchor_y='center')
        
        # create a pubsub receiver
        # update is the topic subscribed to, updateDisplay the callable
        pub.subscribe(self.updateDisplay, "update") 
        
        MessageThread()
        
    def on_draw(self):
        self.clear() 
        self.label.draw()     
            
    def updateDisplay(self, msg):
        """ Receives data from thread and updates the display """
        
        print ("Updating Display")
        self.label.text = msg
            
    def on_close(self):
        """ Override the normal onClose behavior so that we can 
            kill the MessageThread, too
        """
        print("Closing Application")
        global RUN 
        RUN = False
        self.close() # Need to include since defining on_close overrides it


if __name__ == "__main__":
    window = MyGUI()
    pyglet.app.run()
...