Search code examples
pythonpygamepython-multiprocessingmulti-window

Creating two pygame screens using multiprocessing


I am trying to develop an app using pygame and I want to create a popup window.
I am trying to keep it all in one file, so I am using multiprocessing for this task.

I have two classes, the app and the popup window. Each one is inside a function that creates the windows and start both of their loops.

This is some simplified code:

main.py

from multiprocessing import Process

def popup():
    import pygame as pg

    pg.init()

    class PopUp:
        def __init__(self):
            self.screen = pg.display.set_mode((300,300))

        def update(self):
            pg.display.flip()

    p = PopUp()
    while True:
        p.update()

def app():
    import pygame as pg

    pg.init()

    class App:
        def __init__(self):
            self.screen = pg.display.set_mode((800,600))
            self.create_popup()

        def create_popup(self):
            p = Process(target=popup)
            p.start()
            p.join()

        def update(self):
            pg.display.flip()

    a = App()
    while True:
        a.update()

if __name__ == '__main__':
    a = Process(target=app)
    a.start()
    a.join()

However, when I execute this code, only one window appears, with the size of the App, and then is resized to the size of the PopUp, even though it is a different process.

If I do it this other way, then two separate windows will appear with no problem at all.

Why is this happening and how can I get to create the popup window from the app class?


Solution

  • You're duplicating the process after pygame.init() is called. So probably they're sharing window handles, etc.

    If the process is copied before the init(), it works OK.

    import multiprocessing
    import pygame
    import os
    
    def handleUpdates( window, colour ):
        """ Simple pygame message loop.
            Paints the window in a single colour,
            handles quit event """
        clock = pygame.time.Clock()
        exiting = False
    
        while not exiting:
            # Handle user-input
            for event in pygame.event.get():
                if ( event.type == pygame.QUIT ):
                    exiting = True
    
            # draw the window
            window.fill( colour )
            pygame.display.flip()
    
            # save CPU 
            clock.tick( 30 )
    
        pygame.quit()
    
    def pyGameWindow( name, window_pos, colour ):
        """ Initialise PyGame for a new window """
        os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % window_pos
        pygame.init()
        window  = pygame.display.set_mode( ( 300, 300 ) )
        pygame.display.set_caption( name )
        handleUpdates( window, colour )
    
    if __name__ == '__main__':
        p1 = multiprocessing.Process(target=pyGameWindow, args=('Window One', ( 100, 100 ), (255, 0, 0 )))
        p1.start()
        p2 = multiprocessing.Process(target=pyGameWindow, args=('Window Two', ( 500, 100 ), (255, 255, 0 )))
        p2.start()
    
        p1.join()
        p2.join()