Reputation: 31
In my program I'd like users to be able to hold down a button. Upon releasing the button I wish to print the duration that they held down the key. I have been trying to use the pygame clock function but have run into some trouble. The program works fine for the first keypress, but on later keypresses records any downtime between keypresses. Any help would be appreciated, here is my code:
import pygame
from pygame.locals import *
def main():
key = 0
pygame.init()
self = pygame.time.Clock()
surface_sz = 480
main_surface = pygame.display.set_mode((surface_sz, surface_sz))
small_rect = (300, 200, 150, 90)
some_color = (255, 0, 0)
while True:
ev = pygame.event.poll()
if ev.type == pygame.QUIT:
break;
elif ev.type == KEYUP:
if ev.key == K_SPACE: #Sets the key to be used
key += 1 #Updates counter for number of keypresses
while ev.type == KEYUP:
self.tick_busy_loop()
test = (self.get_time()/1000.0)
print "number: ", key, "duration: ", test
ev = pygame.event.poll()
main()
Upvotes: 3
Views: 2962
Reputation: 7303
You can use keyboard
library for this.
Here is a sample code that I made:
import keyboard, time
while True:
a = keyboard.read_event() #Reading the key
if a.name == "esc":break #Loop will break on pressing esc, you can remove that
elif a.event_type == "down": #If any button is pressed (Not talking about released) then wait for it to be released
t = time.time() #Getting time in sec
b = keyboard.read_event()
while not b.event_type == "up" and b.name == a.name: #Loop till the key event doesn't matches the old one
b = keyboard.read_event()
print('Pressed Key "'+ b.name + '" for ' + str(time.time()-t))
If you are looking for more solutions (for Pygame or Pynput), then you can find them on my answer on other related question.
Upvotes: 2
Reputation: 1522
I recommend using get_ticks()
instead of get_time()
. You should read about the differences, but I feel it may not work as desired since you are not explicitly calling self.tick()
.
The problem is your code is outputting the time between each KEYUP
event. There is another way you make the code work by going over the events once per loop and continuing onward without having the nested while
loop.
time_down = 0.0
time_elapsed = 0.0
while True:
for ev in pygame.event.get():
if ev.type == QUIT:
break # you had a semicolon here, there is no need for it
elif ev.type == KEYDOWN:
if ev.key == K_SPACE:
time_down = pygame.time.get_ticks()
elif ev.type == KEYUP:
if ev.key == K_SPACE:
key += 1
time_elapsed = (pygame.time.get_ticks() - time_down)/1000.0
print "number: ", key, "duration: ", time_elapsed
self.tick()
pygame.display.update()
Upvotes: 1