pygame.event.get() not returning any events when inside a thread
You don't get any events at all, because you have to get the events in the main thread.
See the documentation of pygame.event
:
[...] The event subsystem should be called from the main thread.
It is only possible to post events from other thread, but the event queue has to be handled in the main thread.
pygame.event.get() not returning any events when inside a thread
You don't get any events at all, because you have to get the events in the main thread.
See the documentation of pygame.event
:
[...] The event subsystem should be called from the main thread.
It is only possible to post events from other thread, but the event queue has to be handled in the main thread.
pygame.event.get() is not returning any event
pygame.event.get()
grabs all of the events that have registered in the event queue and keeps them in the order they happened. pygame.key.get_pressed()
only has the keys that are pressed in that moment. That means that they have to be pressed when your game tries to access them.
You don't need to use both of these methods together. Instead just loop through the events and do something when a key matches one that you want. A common thing is to react to the cursor keys which is shown below:
import pygame
from pygame.locals import *
pygame.init()
...
...
while True:
#comment
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == pygame.K_DOWN:
print('Down was pressed')
if event.key == pygame.K_UP:
print('Up was pressed')
if event.key == pygame.K_RIGHT:
print('Right was pressed')
if event.key == pygame.K_LEFT:
print('Left was pressed')
pygame.event.get() not returning any events when inside a thread
You don't get any events at all, because you have to get the events in the main thread.
See the documentation of pygame.event
:
[...] The event subsystem should be called from the main thread.
It is only possible to post events from other thread, but the event queue has to be handled in the main thread.
pygame.event.get() not returning any events when inside a thread
You don't get any events at all, because you have to get the events in the main thread.
See the documentation of pygame.event
:
[...] The event subsystem should be called from the main thread.
It is only possible to post events from other thread, but the event queue has to be handled in the main thread.
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)
Related Topics
Updating Openssl in Python 2.7
Opencv 2.4 Videocapture Not Working on Windows
Access a Function Variable Outside the Function Without Using "Global"
Best Practice for Using Assert
How to Create a Copy of an Object in Python
Change One Value Based on Another Value in Pandas
What Is the Intended Use of the Optional "Else" Clause of the "Try" Statement in Python
Slicing a List in Python Without Generating a Copy
How to Load and Play a Video in Pygame
Why Don't These List Operations Return the Resulting List
Check for Presence of a Sliced List in Python
Pandas Long to Wide Reshape, by Two Variables
What Are Logits? Differencebetween Softmax and Softmax_Cross_Entropy_With_Logits
Find Common Substring Between Two Strings
Why Can't Non-Default Arguments Follow Default Arguments