【发布时间】:2013-12-22 10:22:13
【问题描述】:
我在使用基于 SDL 1.2.15 的 pygame 1.9.2 时遇到问题:我看到的以编程方式调整窗口大小的唯一方法是 pygame.display.set_mode(...)。但是当我调用这个方法时,我的键盘状态会被重置,所以所有当前按下的键和修饰符都会发送KEYUP 事件,重复的键也会停止。
通过用户键盘状态手动调整窗口大小是完全正常的。事件队列在调整大小时暂停,然后出现 VIDEORESIZE 和 VIDEOEXPOSE 事件,并且按键仍然被按下,如果是这样的话。
有几个问题:
- 有没有办法在调整窗口大小时保持正常的键盘状态?
- 如果没有,我想至少保留修饰键,但我不能只使用
key.set_mods(),因为我无法获得用户释放键的时刻。 - 最后有没有办法直接调用 SDL 窗口的大小调整?
示例程序演示了不良行为。左右箭头将窗口大小调整为相同,但如果按下它们,则只有一个按键。如果按住,其他键会正常重复。输出是所有发生的事件的事件日志。
import pygame
import sys
# same size all the time
size = (200, 200)
pygame.init()
pygame.display.set_mode(size, pygame.RESIZABLE)
# if left or right arrow key is held nothing will happen despite this line
pygame.key.set_repeat(500, 200)
run = True
while run:
for event in pygame.event.get():
out = '%s\t%s'%(event.type, str(event.dict))
if event.type == pygame.QUIT:
pygame.display.quit()
run = False
if event.type == pygame.KEYDOWN:
# mods are also reset on set_mode() call
out += ', mods = %i' % (pygame.key.get_mods())
if event.key == pygame.K_LEFT:
pygame.display.set_mode(size, pygame.RESIZABLE)
if event.key == pygame.K_RIGHT:
pygame.display.set_mode(size, pygame.RESIZABLE)
print(out)
pygame.time.Clock().tick(60)
在 Win 机器上测试过,如果 linux 也失败了,很快就会报告。
UPD:我一直在研究 pygame 的源代码,但看不出原因,但与 pygame 的源代码捆绑在一起的文档指出,Pygame can only have a single display active at any time. Creating a new one with pygame.display.set_mode() will close the previous display 这意味着无法调整大小窗口,只重新创建它。我觉得有点奇怪。
UPD:我已经改变了我的程序行为,以便在用户完全释放键盘之前不会实际发生调整大小。它运行良好且不会破坏可用性。
不过,很高兴知道是否存在针对所述问题的解决方案。
【问题讨论】:
-
真的很简单。将键的状态存储在您可以控制的数组中。
-
你是说如果
K_LEFT和K_RIGHT同时被按下,那么只会找到一个KEYDOWN事件? -
@Haz,不,如果按下并按住其中任何一个,就会有 一个
KEYDOWN和一个KEYUP
标签: python keyboard pygame sdl