Pygame Window Not Responding After Few Seconds

Pygame window not responding after a few seconds

Call pygame.event.get() at the beginning of the while loop.

Pygame windows isn't responding after a few seconds of running

You missed to update the display at the end of main by pygame.display.flip(). Furthermore you have to control the frames per second with pygame.time.Clock.tick in the application loop:

def main():
# [...]

while not done:
# [...]

pygame.display.flip()
clock.tick(60)

Pygame Window not Responding after few seconds

Your game is not responding, because you ask for an input inside the application loop. input stops the application loop and waits for input to be confirmed. If you stop the application loop, the window stops responding. Use the KEYDOWN event to get an input in PyGame (see pygame.event):

for event in pygame.event.get():
# [...]

if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)

guessed has to be initialized before the application loop. Don't reset it in the loop:

import pygame
pygame.init()

running = True

window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))

clock = pygame.time.Clock()

word = "something"
guessed = []

answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)

while running:
dt = clock.tick(60)

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)

pygame.quit()

How to read realtime microphone audio volume in python and ffmpeg or similar

Thanks to @Matthias for the suggestion to use the sounddevice module. It's exactly what I need.

For posterity, here is a working example that prints real-time audio levels to the shell:

# Print out realtime audio volume as ascii bars

import sounddevice as sd
import numpy as np

def print_sound(indata, outdata, frames, time, status):
volume_norm = np.linalg.norm(indata)*10
print ("|" * int(volume_norm))

with sd.Stream(callback=print_sound):
sd.sleep(10000)

Sample Image

Pygame windows not responding if the program is slow

You will need to make sure the operating system window events are being handled, or you do get that dreaded "Not Responding" thing, exactly because, well, you're not responding to events.

In general, games always have a main loop which runs all the time and pumps events, updates game logic, draws the screen and so on. (Depending on the complexity of the app and how you design things, menus might have another loop, but that's beside the point.)

Using threads

To run things concurrently in your program, you might think you can pump these events in another thread, but that's not safe to do with Pygame, so you'll instead need to do all the other things in a secondary thread:

Caution: pygame.event.pump() should only be called in the thread that initialized pygame.display.

Using threads will get a little hairy since there's no direct way to return a value from the thread, and knowing whether a thread is done also takes an event. Something like this (might be buggy) should do the trick.

import threading

def engine_play(finish_event, output_list):
# Here the engine searches for the best move for some time
a = 0
for _ in range(1000000000):
a += _
output_list.append(a) # could also use a queue
finish_event.set()

def run_engine_play():
finish_event = threading.Event()
output_list = []
thread = threading.Thread(target=engine_play, args=(finish_event, output_list))
thread.start()
return (finish_event, output_list)

finish_event, output_list = run_engine_play()

while True:
for event in pygame.event.get():
pass # handle events...
if finish_event.is_set():
print(output_list[0])

Using futures

You could abstract away the complexity of threads by using concurrent.futures, but the main point stands: you have a task (a future) you'll need to wait to finish.

Using a generator

You can turn engine_play() into a generator function to avoid using threads, but you'll need to take care that the engine function yields control back to the main loop every now and then.


def engine_play():
# Here the engine searches for the best move for some time
a = 0
for _ in range(1000000000):
a += _
if _ % 1000 == 0: # every now and then, let the loop do other things
yield None # Not done yet...
yield a

# Instantiate the generator
engine_play_gen = engine_play()

while True:
for event in pygame.event.get():
pass # handle events...
val = next(engine_play_gen) # let the engine do its thing
if val is not None:
print(val)

Why does my pygame show not responding after a few seconds?

It's blocking the event queue processing when Clicker becomes True. So once clicker starts looping, no user-input is handled as this loop never re-examines the queue for new events, and just continues to re-process the same (old) event result.

You probably need to merge the event handling in the while Clicker cause into the main event loop. Maybe with an if Clicker on those events:

pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)

while running:
# handle events and user interaction
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

if event.type == pygame.KEYDOWN : # some key was pushed
if event.key == pygame.K_p:
print('started')
Clicker = True # start the clicker
elif event.key == pygame.K_x:
print('stopped')
Clicker = False # stop the clicker
elif event.key == pygame.K_z:
running = False # Allow exit here too

# Update the screen
if Clicker:
# Click mode
display_surface.fill(white)
display_surface.blit(Run_Text, Run_Text_pos)
else:
# NOT in Click Mode
display_surface.fill(white)
display_surface.blit(Start_Text, Continue_pos)
display_surface.blit(Pause_Text, Pause_Text_pos)

Img(x, y)
pygame.display.update()

Something close to that anyway. Without comments, it's not immediately clear what the intention of the code is, so it's hard to create an exacting solution.

Pygame 'not responding' during animations

You have to handle the events in the application loop. See pygame.event.get() respectively pygame.event.pump():

For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.

while player.x != target_x and player.y != target_y:

pygame.event.pump() # <--- this is missing

if player.x < target_x:
player.x += 1
else:
player.x -= 1

if player.y < target_y:
player.y += 1
else:
player.y -= 1

draw() # updates / draws the screen
clock.tick(30)


Related Topics



Leave a reply



Submit