1

I'm trying to draw an image with PyGame, and I copied this code from Adafruit. It's strange, seems nothing displays on the screen until I Ctrl-C, at which time it shows the image. Then the image stays on the screen until I press Ctrl-C again. I then get the following message:

Traceback (most recent call last):
File "RaspiDisplay.py", line 60, in
time.sleep(10)
KeyboardInterrupt

What's going on? By the way, I'm running this via ssh on a raspberry pi, with Display set to 0 (my TV) If I put a print statement in init, that also doesn't print until I press Ctrl-C.

import os
import pygame
import time
import random

class pyscope :
    screen = None;

    def __init__(self):
        "Ininitializes a new pygame screen using the framebuffer"
        # Based on "Python GUI in Linux frame buffer"
        # http://www.karoltomala.com/blog/?p=679
        disp_no = os.getenv("DISPLAY")
        if disp_no:
            print "I'm running under X display = {0}".format(disp_no)

        # Check which frame buffer drivers are available
        # Start with fbcon since directfb hangs with composite output
        drivers = ['fbcon', 'directfb', 'svgalib']
        found = False
        for driver in drivers:
            # Make sure that SDL_VIDEODRIVER is set
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
            except pygame.error:
                print 'Driver: {0} failed.'.format(driver)
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
        print "Framebuffer size: %d x %d" % (size[0], size[1])
        self.screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
        # Clear the screen to start
        self.screen.fill((0, 0, 0))        
        # Initialise font support
        pygame.font.init()
        # Render the screen
        pygame.display.update()

    def __del__(self):
        "Destructor to make sure pygame shuts down, etc."

    def test(self):
        # Fill the screen with red (255, 0, 0)
        red = (255, 0, 0)
        self.screen.fill(red)
        # Update the display
        pygame.display.update()

# Create an instance of the PyScope class
scope = pyscope()
scope.test()
time.sleep(10)
3
  • Try running your program with strace to see what it is waiting on. Commented Jun 2, 2013 at 5:01
  • Well, I ran strace, and it seems my program's getting stuck on: ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 ioctl(4, KDGKBENT, 0xbe90befc) = 0 Commented Jun 2, 2013 at 5:09
  • Why are you doing time.sleep(10)? I'm about 80% sure that's where your problem is. You're making the whole program wait around for 10 seconds, which means the pygame event loop doesn't get a chance to run for 10 seconds, which is exactly what you're seeing. Commented Jun 2, 2013 at 5:10

1 Answer 1

2

You're not running an event loop anywhere. Instead, you're just initializing everything, and then going to sleep for 10 seconds. During that 10 seconds, your code is doing nothing, because that's what you told it to do. That means no updating the screen, responding to mouse clicks, or anything else.

There are a few different ways to drive pygame, but the simplest is something like this:

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
        # any other event handling you need
    # all the idle-time stuff you want to do each frame
    # usually ending with pygame.display.update() or .flip()

See the tutorial for more information.


As a side note, your initialization code has a bunch of problems. You iterate through three drivers, but you only set SDL_VIDEODRIVER once, so you're just trying 'fbcon' three times in a row. Also, you've got code to detect the X display, but you don't allow pygame/SDL to use X, so… whatever you were trying to do there, you're not doing it. Finally, you don't need a found flag in Python for loops; just use an else clause.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.