1

Recently i completed learning about threading in python and now trying to implement it in a program. And here is the code:

from threading import Thread
from time import sleep
import pygame as py

py.init()

X,Y = 900, 800
APP = py.display.set_mode((X, Y))
APP = py.display.set_caption("Test")

def exit_app():
    "To terminate program."
    while True:
        for eve in py.event.get():
            if eve.type == py.QUIT:
                py.quit()
                exit()

def update_display():
    "Update pygame window"
    while True:
        sleep(3)
        py.display.update()

if __name__ == "__main__":
    Thread(target=exit_app).start()
    Thread(target=update_display).start()

Now the problem is that after creating thread i ran into a problem. When i tried to run code it get executed without any problem but when the code exit(i.e., when i close the pygame window) i get to see the error as follows:

$python3 test.py
pygame 2.0.1 (SDL 2.0.14, Python 3.9.4)
Hello from the pygame community. https://www.pygame.org/contribute.html
Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/home/cvam/Documents/test.py", line 23, in update_display
    py.display.update()
pygame.error: video system not initialized      
Cvam
  • 11
  • 2
  • In general, [pygame can't be used on different threads.](https://stackoverflow.com/questions/2970612/pygame-in-a-thread). – MegaIng May 03 '21 at 11:26

1 Answers1

1

Ok, so first of all it seems like you are trying to create separate functions with infinite loops for updating the screen and for event handling, to clear the same, all of it can be done in one loop and is perhaps better way of doing the same.[Thus I have removed the exit_app and the update_display function since they use two other infinite while loops.]

Secondly there is no need to use a separate thread for event handling, since the event handling can be done in the same loop, when you create a separate thread for it with an infinite while loop, then that results in confusion as to which thread pygame shall run on, the main thread or the THREAD1.[Thus the same has been commented out.]

Also placing pygame.init function call and all other statements that were before outside inside the if name == 'main' block seems to ensure that they are executed. Also placing them before the thread starts makes sure that they are executed and that pygame stuff is initialized before the thread executes.

Also some suggestions -:

  • Instead of the sleep function from the time module, a similar function of the pygame time module namely the pygame.time.delay function can be used, its present within pygame and thus is more suitable to use.

  • I have experienced many errors while quitting the pygame programs using the inbuilt exit and quit functions, and thus seem to prefer using exit function of the sys module of python since it leads to less errors in most cases.

The code for the same shall become -:

# from threading import Thread
# from time import sleep
import pygame
import sys

if __name__ == "__main__":
    pygame.init()

    X,Y = 900, 800
    APP = pygame.display.set_mode((X, Y))
    APP = pygame.display.set_caption("Test")
    
    # # By detecting the events within the main game loop there is no need
    # # to call a separate thread, and the same may not be working since the two
    # # threads the main one and the THREAD1 are both containing infinite loops and pygame
    # # can only take over one at a time.
    # THREAD1=Thread(target=exit_app)
    # THREAD1.start()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit() # sys module's exit method seems to be better and causes less errors at exit
        
        # # Without a delay the window will still not close incase this script is being
        # # used for that purpose by you.
        # pygame.time.delay(3) # Pygame alternative to sleep method of time module https://www.pygame.org/docs/ref/time.html#pygame.time.delay
        pygame.display.update()
        continue
    
    pass
typedecker
  • 1,351
  • 2
  • 13
  • 25
  • Also incase you still want to execute a thread using this program, better not include an infinite while loop in it's callback function. – typedecker May 03 '21 at 14:34
  • Please do not start the answer with *"Ok, ..."*. – Rabbid76 May 03 '21 at 14:53
  • Yup, sure I will keep it in mind, for the next time and if possible make an edit in my answer thanks for the feedback. – typedecker May 03 '21 at 14:55
  • Thanks for spending time on my question, but the program was just a sample, i need to know how to use multi-threading along with pygame. – Cvam May 03 '21 at 16:50
  • And yes i did many small projects in pygame. – Cvam May 03 '21 at 16:52
  • Oh ok, sorry if you felt bad I did not mean to offend you, But if you specifically want to integrate multi threading with pygame, then check out [Multi-Threading with Pygame](https://stackoverflow.com/questions/7141665/multithreading-with-pygame) – typedecker May 04 '21 at 07:59
  • I checked the given link but he also told the alternate way in the answer instead of using thread. – Cvam May 04 '21 at 11:57
  • And by the way thanks for your effort. – Cvam May 04 '21 at 11:57