Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pygame requires keyboard interrupt to init display

I'm trying to initialize pygame on a Raspberry Pi and its requiring a keyboard interrupt before it will do anything. Here's my code:

    os.putenv ( "SDL_VIDEODRIVER" , "fbcon" )
    pygame.display.init()    # It hangs here
    screen = pygame.display.set_mode ( ( 1024 , 768 ) )

    pygame.draw.rect ( screen , ( 0 , 255 , 0 ) , ( 15 , 15 , 15 , 15 ) )
    pygame.display.flip()

    keyLoop = True
    while keyLoop:
       for event in pygame.event.get():
          if event.type == pygame.KEYDOWN:
             if event.key == pygame.K_DOWN:
                print ( "Down arrow pressed, exiting" )
                keyLoop = False
                pygame.quit()

I found a similar question here Python program won't respond until keyboard interrupt but it wouldn't let me add a comment and I've tried all of their suggestions and still have the problem. If I press CTRL + C then my graphics appear but then the keyboard doesn't work.

Thanks

EDIT

I got it to work by removing os.putenv completely. The problem was actually in the Pi setup in config.txt. I was trying to init a pygame display bigger than the Pi's framebuffer. Making sure the two match (framebuffer and display.set_mode) made it start up just fine.

like image 445
scottinthebooth Avatar asked Jun 11 '13 02:06

scottinthebooth


2 Answers

I had exactly the same problem but it would only happen on second running of my pygame code (i.e. first run on boot, everything is OK but if you stop the program and then try to restart it there is then a hang at pygame.init or pygame.display.set_mode).

The solution from someone-or-other did not work for me (the raising of the keyboard interrupt did not seem to hit the main thread, just the forked thread) but thanks for the idea! A resulting working code fragment is as follows.

from signal import alarm, signal, SIGALRM, SIGKILL

def init_Pygame():

    # this section is an unbelievable nasty hack - for some reason Pygame
    # needs a keyboardinterrupt to initialise in some limited circs (second time running)
    class Alarm(Exception):
        pass
    def alarm_handler(signum, frame):
        raise Alarm
    signal(SIGALRM, alarm_handler)
    alarm(3)
    try:
        pygame.init()
        DISPLAYSURFACE = pygame.display.set_mode((DISPLAYWIDTH, DISPLAYHEIGHT)) 
        alarm(0)
    except Alarm:
        raise KeyboardInterrupt

    pygame.display.set_caption('Drawing')
    [...rest of initialisation...]

Although this is a solution, I don't know what causes the behaviour.

like image 145
BBUK Avatar answered Sep 23 '22 13:09

BBUK


I think this happens because pygame is still connected to the display. I get the same thing if I kill a process that is using pygame to display objects on an Adafruit PiTFT. After a reboot it runs fine, but if I kill it and try to start it again it hangs on this line:

screen = pygame.display.set_mode(size)

So I tried catching the SIGTERM and doing a pygame.quit():

import sys, signal

def signal_handler(signal, frame):
  print 'Signal: {}'.format(signal)
  sleep(1)
  pygame.quit()
  sys.exit(0)

[...]

signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
while ...

Now I kill the process or interrupt it with ctrl-c, I can run it again without having to hit Ctrl-C to get it going.

William

like image 23
wbp Avatar answered Sep 23 '22 13:09

wbp