pygame window 单击时无响应
pygame window not responding when clicked
我正在使用 pygame 进行我正在处理的项目的界面显示和控制器输入。目前一切都很好,所以这不是主要问题,但如果在实际使用过程中不小心发生,可能会出现一些问题,所以我想尽可能地修复它。
当我 运行 我的代码时,pygame window 完全按照预期出现、显示和更新。但是,如果我单击它或它以其他方式获得焦点,window 会冻结并变为(无响应)。代码本身继续 运行ning,包括负责更新显示的线程,直到我关闭 window 所以 Python 本身仍然 运行ning 正常,但是window 停止工作。
我的更新循环代码在这里,它真的很丑陋:
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
关于 window 外观的 image,以帮助您更好地理解代码。
事件队列可能已满,无法处理更多事件,因此 OS 表示 window 没有响应。
如果您对任何事件都不感兴趣,您应该通过调用 pygame.event.clear()
来清除事件队列,但也许您想要最少处理 pygame.QUIT
,因此调用 pygame.event.get()
(没有一个参数)也可以解决问题。
很遗憾,我无法 运行 您发布的用于测试我自己的代码,但我想指出一些可能会有所帮助的事情。首先,这不是终止程序的正确方法,至少不是我所知道的方法。我在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。
最后,老实说,我不知道为什么您的 window 在收到鼠标输入后会停止响应,但如果这确实是罪魁祸首,您可以简单地阻止鼠标事件。在你的 while 循环之前试试这个:
pygame.mouse.set_visible(False)
pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)
这应该忽略鼠标的所有输入,您甚至无法在 window 上看到它。
我将这段代码移到了主线程而不是线程,它现在可以工作了。我确实最终需要 pygame.event.pump() 行,现在我使用 clock.tick() 进行速率控制,但它在其他方面是相同的,但移动了。显然 pygame 不能很好地处理线程。
虽然感谢所有帮助,实际的解决方案可能是意外发现的,但有东西可以尝试让我尝试了足够长的时间来尝试我没想到的东西。
问题是线程,我有同样的问题,如果我 运行 pygame 在线程中更新,当我改变焦点时它会锁定,如果我 运行 它没有线程相同的代码工作正常。解决方法是确保 'pygame' 仅从您的主线程调用,然后其他代码可以在其他线程中,但与 pygame 相关的任何内容都应来自主线程。无论如何,这对我有用。
我正在使用 pygame 进行我正在处理的项目的界面显示和控制器输入。目前一切都很好,所以这不是主要问题,但如果在实际使用过程中不小心发生,可能会出现一些问题,所以我想尽可能地修复它。
当我 运行 我的代码时,pygame window 完全按照预期出现、显示和更新。但是,如果我单击它或它以其他方式获得焦点,window 会冻结并变为(无响应)。代码本身继续 运行ning,包括负责更新显示的线程,直到我关闭 window 所以 Python 本身仍然 运行ning 正常,但是window 停止工作。
我的更新循环代码在这里,它真的很丑陋:
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
关于 window 外观的 image,以帮助您更好地理解代码。
事件队列可能已满,无法处理更多事件,因此 OS 表示 window 没有响应。
如果您对任何事件都不感兴趣,您应该通过调用 pygame.event.clear()
来清除事件队列,但也许您想要最少处理 pygame.QUIT
,因此调用 pygame.event.get()
(没有一个参数)也可以解决问题。
很遗憾,我无法 运行 您发布的用于测试我自己的代码,但我想指出一些可能会有所帮助的事情。首先,这不是终止程序的正确方法,至少不是我所知道的方法。我在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。
最后,老实说,我不知道为什么您的 window 在收到鼠标输入后会停止响应,但如果这确实是罪魁祸首,您可以简单地阻止鼠标事件。在你的 while 循环之前试试这个:
pygame.mouse.set_visible(False)
pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)
这应该忽略鼠标的所有输入,您甚至无法在 window 上看到它。
我将这段代码移到了主线程而不是线程,它现在可以工作了。我确实最终需要 pygame.event.pump() 行,现在我使用 clock.tick() 进行速率控制,但它在其他方面是相同的,但移动了。显然 pygame 不能很好地处理线程。
虽然感谢所有帮助,实际的解决方案可能是意外发现的,但有东西可以尝试让我尝试了足够长的时间来尝试我没想到的东西。
问题是线程,我有同样的问题,如果我 运行 pygame 在线程中更新,当我改变焦点时它会锁定,如果我 运行 它没有线程相同的代码工作正常。解决方法是确保 'pygame' 仅从您的主线程调用,然后其他代码可以在其他线程中,但与 pygame 相关的任何内容都应来自主线程。无论如何,这对我有用。