我正在尝试在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)使它启动就好了。
答案 0 :(得分:7)
我有完全相同的问题,但它只会在我的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...]
虽然这是一个解决方案,但我不知道导致这种行为的原因。
答案 1 :(得分:2)
我认为这是因为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来启动它。
威廉
答案 2 :(得分:1)
Pygame.init()永远不会导致这种情况(除非你在python中发现了一个错误,非常不可能),但os.putenv()很可能会导致这种情况。这可能无法解决您的问题,但最好在os.environ中设置您的更改而不是在os.putenv()中更改它在OSX上也不起作用,因此如果您在OSX上使用它可能会有错误。最后一个可能的解决方案是只为你的问题补丁工作。这是一个混乱的解决方案,除非你找不到任何其他东西,否则不应该实现,但只要程序在键盘中断后工作正常,它就可以工作。您可以使程序自动导致键盘中断事件。一种方法是启动计时器,这将引发键盘中断。唯一困难的是它必须在后台运行才能在必要时引发中断。您可以使用线程模块执行此操作。这是一个补丁。 (记得尽量不要使用它并不理想)
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()
这应该可以使它发挥作用。