user2980167
user2980167

Reputation: 31

Detecting duration of a keypress python/pygame

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

Answers (2)

Nouman
Nouman

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

Leonardo
Leonardo

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

Related Questions