Quick answer: key.set_repeat only generates repeated KEYDOWN events on the event queue. It does nothing for key.get_pressed() polling — read the event queue instead.
A text input field calls pygame.key.set_repeat(300, 30) but holding a key still types one character. The code uses get_pressed() polling, which set_repeat doesn’t affect.
set_repeat Affects the Event Queue
pygame.key.set_repeat(300, 30) # delay 300ms, then every 30ms
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_BACKSPACE:
text = text[:-1]
elif event.unicode:
text += event.unicode
With repeat enabled, holding a key fires KEYDOWN events at the repeat rate. Read them from the event queue.
get_pressed Is Level State
# this is just "is the key down right now?" — no repeat concept
keys = pygame.key.get_pressed()
if keys[pygame.K_BACKSPACE]:
...
get_pressed returns a snapshot of held keys. It has no notion of repeat — that’s why set_repeat seems to do nothing here.
Which to Use
- Text input / menus: event queue + set_repeat — you want auto-repeat.
- Gameplay movement: get_pressed polling — you want continuous “is held”, not discrete repeats.
Disable Repeat
Call pygame.key.set_repeat() with no arguments to turn it off — important when switching from a menu back to gameplay so movement doesn’t get repeat artifacts.
Verifying
In the text field, holding a key repeats after the delay. Switching to gameplay, movement is smooth via polling. No crosstalk between the two input styles.
“set_repeat is an event-queue feature. Polling with get_pressed ignores it entirely.”
Toggle set_repeat on when a text field gains focus, off when it loses focus — clean separation from gameplay input.