【问题标题】:pygame requires keyboard interrupt to init displaypygame 需要键盘中断来初始化显示
【发布时间】:2013-06-06 19:21:13
【问题描述】:

我正在尝试在 Raspberry Pi 上初始化 pygame,它需要键盘中断才能执行任何操作。这是我的代码:

    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()

我在这里Python program won't respond until keyboard interrupt 发现了一个类似的问题,但它不允许我添加评论,我已经尝试了他们的所有建议,但仍然存在问题。如果我按 CTRL + C,然后我的图形会出现,但键盘不起作用。

谢谢

编辑

我通过完全删除 os.putenv 让它工作。问题实际上出在 config.txt 中的 Pi 设置中。我试图初始化一个比 Pi 的帧缓冲区更大的 pygame 显示。确保两者匹配(framebuffer 和 display.set_mode)使其启动正常。

【问题讨论】:

  • 按下一个键后,它会正确渲染 Rect 吗?在我搜索 rPi 示例时,他们没有设置环境变量,也许可以尝试不设置。
  • 我必须按 Ctrl + C 才能获取视频。环境变量是因为我在 X 之外运行,直接渲染到帧缓冲区。我会删除它,看看它是怎么做的。
  • 这与 HDMI 一起工作!今晚我会用复合输出试一试。
  • 没有运气的复合,同样的行为。我修改了 config.txt 以强制复合,但这是同样的问题。
  • 我没有 Raspberry Pi,所以这只是一个疯狂的猜测......但你有没有试过在 display.flip() 之后在 keyLoop 循环之前抽一次 Pygame 事件队列?跨度>

标签: python pygame raspberry-pi


【解决方案1】:

Pygame.init() 永远不会导致这种情况(除非您实际上在 python 中发现了错误,这不太可能),但是 os.putenv() 很可能会导致这种情况。这可能无法解决您的问题,但最好在 os.environ 中设置更改而不是在 os.putenv() 中设置它也不适用于 OSX,因此如果您在 OSX 上使用它可能会出现错误。最后一种可能的解决方案是只为您的问题提供补丁。这是一个混乱的解决方案,除非您找不到其他任何东西,否则不应实施,但它会起作用,前提是程序在您的键盘中断后可以正常工作。您可以使程序自动引起键盘中断事件。一种方法是启动一个定时器,它会引发一个键盘中断。唯一困难的一点是它必须在后台运行以在必要时引起中断。您可以使用 threading 模块来执行此操作。这是一个补丁。 (记得尽量不要用这个不太理想)

import threading
import time

def timer():
    time.sleep(0.5)
    raise KeyboardInterrupt

interrupter = threading.Thread(target=timer)
interrupter.start()
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()

这应该可以正常工作。

【讨论】:

    【解决方案2】:

    我遇到了完全相同的问题,但它只会在我的 pygame 代码第二次运行时发生(即第一次在启动时运行,一切正常,但如果你停止程序然后尝试重新启动它,那么 pygame 就会挂起.init 或 pygame.display.set_mode)。

    某人或其他人的解决方案对我不起作用(提高键盘中断似乎没有击中主线程,只是分叉线程)但感谢您的想法!生成的工作代码片段如下。

    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...]
    

    虽然这是一个解决方案,但我不知道是什么导致了这种行为。

    【讨论】:

    • 在 Raspberry Pi 2、Jessie、Python 2.7.9、pygame、Adafruit PiTFT 下运行出色的出色解决方案
    【解决方案3】:

    我认为这是因为 pygame 仍然连接到显示器。如果我杀死一个使用 pygame 在 Adafruit PiTFT 上显示对象的进程,我会得到同样的结果。重新启动后它运行良好,但如果我杀死它并尝试再次启动它,它会挂在这一行:

    screen = pygame.display.set_mode(size)
    

    所以我尝试捕捉 SIGTERM 并执行 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 ...
    

    现在我用 ctrl-c 终止进程或中断它,我可以再次运行它而无需按 Ctrl-C 来启动它。

    威廉

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多