我正在使用pygame进行界面显示和控制器输入我正在进行的项目。目前一切都运作良好,所以这不是一个主要问题,但如果它在实际使用中偶然发生可能会有一些问题,所以我想修复它。
当我运行我的代码时,pygame窗口会按预期显示,显示和更新。但是,如果我点击它或它以某种其他方式获得焦点,窗口会冻结并变为(无响应)。代码本身继续运行,包括负责更新显示的线程,直到我关闭窗口使Python本身仍然正常运行,但窗口停止工作。
我的更新循环代码就在这里,其中非常丑陋的荣耀:
while(1):
print "thread is fine"
pygame.event.pump()
if LOV_Flag == 1:
videoColor = (255, 0, 0)
else:
videoColor = (0, 255, 0)
# Refresh the screen and redraw components
screen.fill((255, 255, 255))
pulseLabel = pulseFont.render("Pulse: ", 1, (0, 0, 0))
videoLabel = videoFont.render("Video: ", 1, (0, 0, 0))
motorsLabel = labelFont.render("Motors", 1, (0, 0, 0))
motorLabel = captionFont.render("L R", 1, (0, 0, 0))
armLabel = captionFont.render("Arm", 1, (0, 0, 0))
gripperLabel = captionFont.render("Gripper", 1, (0, 0, 0))
screen.blit(motorsLabel, (55, 50))
screen.blit(motorLabel, (60, 75))
screen.blit(pulseLabel, (300, 19))
screen.blit(videoLabel, (300, 45))
screen.blit(armLabel, (250, 75))
screen.blit(gripperLabel, (235, 255))
leftBar = (50, 200 - drive.getSpeed()[0], 25, drive.getSpeed()[0])
rightBar = (100, 200 - drive.getSpeed()[1], 25, drive.getSpeed()[1])
armBar = (250, 200 - (100 * arm.report()), 25, (100 * arm.report()))
upperArmBar = (250, 200 - (100 * arm.reportUp()), 25, 2) # 100 is the value on the bar
lowerArmBar = (250, 200 - (100 * arm.reportDown()), 25, 2) # 135 (65) is the value on the bar
gripperBar = (212, 225, (100 * hand.report()), 25)
leftGripperBar = (212 + (100 * hand.reportClosed()), 225, 2, 25)
rightGripperBar = (212 + (100 * hand.reportOpen()), 225, 2, 25)
pygame.draw.rect(screen, (255, 0, 0), leftBar, 0)
pygame.draw.rect(screen, (255, 0, 0), rightBar, 0)
pygame.draw.rect(screen, (255, 0, 0), armBar, 0)
pygame.draw.rect(screen, (0, 0, 0), upperArmBar, 0)
pygame.draw.rect(screen, (0, 0, 0), lowerArmBar, 0)
pygame.draw.rect(screen, (255, 0, 0), gripperBar, 0)
pygame.draw.rect(screen, (0, 0, 0), leftGripperBar, 0)
pygame.draw.rect(screen, (0, 0, 0), rightGripperBar, 0)
pygame.draw.circle(screen, pulseColor, [370, 32], 10)
pygame.draw.circle(screen, videoColor, [370, 58], 10)
pygame.display.update()
time.sleep(0.1)
if killFlag:
return
关于窗口外观的image,以防止您更好地理解代码。
答案 0 :(得分:1)
不幸的是,我无法运行您发布的代码来测试自己,但有一些我想指出的可能会有所帮助。首先,这不是杀死程序的正确方法,至少不是我所知道的方式。我在pygame中使用的是:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
循环结束时的time.sleep(1)是否试图控制帧速率?如果是这样,使用pygame时钟可以提供更好的服务。在主循环之前初始化一个时钟,如下所示:
clock = pygame.time.Clock()
然后在主循环中使用:
clock.tick(60)
这样做是将程序设置为以您想要的fps运行。在这种情况下,它设置为60。
最后,老实说,我不知道为什么你的窗口会在收到鼠标输入后停止响应,但如果这确实是罪魁祸首你可以简单地阻止鼠标事件。在while循环之前尝试这个:
pygame.mouse.set_visible(False)
pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)
这应该忽略鼠标的所有输入,你甚至无法在窗户上看到它。
答案 1 :(得分:0)
事件队列可能已填满,无法处理更多事件,因此操作系统说窗口没有响应。
如果您对任何事件不感兴趣,则应该通过调用pygame.event.clear()
来清除事件队列,但是您可能希望至少处理pygame.QUIT
,因此请调用pygame.event.get()
(不一个参数)也会做到这一点。
答案 2 :(得分:0)
我将此代码移至main而非线程,现在可以正常工作。我最终需要pygame.event.pump()行,现在我使用clock.tick()进行速率控制,但它在其他方面相同但移动了。显然pygame在线程化方面表现不佳。
感谢所有的帮助,实际的解决方案可能是偶然发现的,但有些事情让我尝试让我尝试的时间足够长,以便尝试我不希望工作的事情。
答案 3 :(得分:0)
问题是线程,我遇到了同样的问题,如果我在线程中运行pygame更新,则在更改焦点时它会锁定,如果我在没有线程的情况下运行,则相同的代码可以正常工作。解决方法是确保仅从您的原始主线程中调用“ pygame”,然后其他代码可以位于其他线程中,但是与pygame相关的所有操作都应来自主线程。无论如何,这对我有用。