2010-06-03 5 views
2

Je souhaite utiliser un programme pyGame dans le cadre d'un autre processus. En utilisant le code suivant, pyGame ne semble pas traiter les événements; il ne répond pas à la touche 'q' et ne dessine pas la barre de titre de la fenêtre. Si go() n'est pas exécuté en tant que thread, cela fonctionne correctement. C'est sous OSX; Je ne sais pas si c'est le problème ou non.pyGame dans un thread

import pygame, threading, random 

def go(): 
    pygame.init() 
    surf = pygame.display.set_mode((640,480)) 
    pygame.fastevent.init() 

    while True: 
    e = pygame.fastevent.poll() 
    if e.type == pygame.KEYDOWN and e.unicode == 'q': 
     return 

    surf.set_at((random.randint(0,640), random.randint(0,480)), (255,255,255)) 
    pygame.display.flip() 

t = threading.Thread(target=go) 
t.start() 
t.join() 
+0

Votre code fonctionne bien sur ma machine (linux). – nosklo

+1

Fonctionne également sur ma machine Linux, semble être un problème spécifique à OSX. –

+0

Fonctionne correctement sur les fenêtres – Emma

Répondre

2

Il est préférable d'effectuer la gestion des événements et des graphiques dans le thread principal. Certains environnements n'aiment pas vraiment que vous essayiez de rendre d'autres threads, et certains n'aiment pas que vous essayiez de drainer la file d'attente d'événements d'eux non plus.

Il se peut même que vous ne puissiez pas faire ce que vous espérez faire, car le processus que vous utilisez peut très bien avoir ses propres idées sur la personne à qui appartient la file d'attente et la fenêtre de rendu.

2

Pas vraiment une réponse, juste une affirmation du fait que ce problème se produit effectivement sur Mac OS X et non sur Linux. J'ai développé mon programme sur Ubuntu et ce genre de code a bien fonctionné là-bas, mais il a échoué comme vous l'avez décrit lorsque j'ai essayé de l'exécuter sur un Mac. L'exécution du code de dessin dans le thread principal fonctionne plutôt bien. Si c'est vraiment une limitation du module de threading ou de pygame (sur Mac), alors je suppose que le seul moyen est de restructurer votre programme pour que tout le dessin soit géré par le thread principal. Vous pouvez également déposer un rapport de bogue et voir ce qui se passe.

EDIT: Une autre option, bien meilleure, consisterait à utiliser le module multiprocessing. Vous pourriez générer un processus python séparé juste pour le rendu à l'écran. Les processus peuvent ensuite communiquer des informations les uns aux autres. Je cherche à l'utiliser moi-même.

3

Pygame n'est pas threadsafe et le eventloop est requis pour fonctionner sur le thread principal! Sinon, le problème que vous décrivez peut se produire.

Une solution consiste à appeler pygame.mainloop() à partir du thread principal.

Toutefois, vous utilisez peut-être d'autres modules qui doivent également être exécutés à partir du thread principal. Il y a dans ce cas une solution pythonique. vous avez la possibilité d'exécuter pygame mainloop avec un argument. Cet argument signifie: exécuter le mainloop pendant quelques secondes seulement. Par conséquent, ce que vous pouvez faire est de créer un générateur qui exécute mainloop pendant 0,1 seconde que vous appelez périodiquement à partir du thread principal. Par exemple:

def continue_pygame_loop(): 
    pygame.mainloop(0.1) 
    yield 

alors il suffit d'appeler continue_pygame_loop() périodiquement de fil conducteur

Tkinter souffre du même problème, mais n'a aucun moyen de spécifier runloop() avec un délai d'attente. Pour moi, c'est pourquoi pygame est génial!

+1

Pour autant que je sache et puisse le savoir, 'pygame' n'a pas de fonction' mainloop() '. (J'utilise v1.9.2), donc on ne sait pas de quoi vous parlez. Comme vous le confondez avec 'tkinter' (qui fait)? – martineau

2

Vous avez peut-être une vue longue, mais essayez de ne pas importer de Pygame tant que vous n'êtes pas dans le fil. C'est à peu près possible que le problème est que vous importez Pygame sur un thread et que vous l'utilisez sur un autre thread. Cependant, l'importation sur plusieurs threads peut avoir d'autres problèmes. En particulier, assurez-vous qu'une fois que vous avez démarré le thread Pygame, vous l'attendez pour terminer l'importation avant de faire quoi que ce soit qui pourrait provoquer l'arrêt du processus Python, ou vous pourriez obtenir un blocage.

+0

Cela a certainement fonctionné pour moi sur Windows avec Python 3.3.5 – zmechanic