KeyPress event with holding down the key

Reply

Join Date: Feb 2007
Posts: 77
Reputation: aot is an unknown quantity at this point 
Solved Threads: 1
aot's Avatar
aot aot is offline Offline
Junior Poster in Training

KeyPress event with holding down the key

 
0
  #1
Feb 22nd, 2007
I've been trying to use binding to a KeyPress/KeyRelease such that a particular function runs as long as the key is pressed and ceases when it is released. However, it seems like my major problem is that most keys are considered to continually activate as long as you hold them down... so my function either appears to start over and over again or sometimes immediately ends right after the key is first pressed. Does anyone have any advice?
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 3,956
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 917
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: KeyPress event with holding down the key

 
0
  #2
Feb 22nd, 2007
That may be tough because a continuous key press is interpreted by your operating system as a repeated key press.
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: KeyPress event with holding down the key

 
0
  #3
Feb 22nd, 2007
In elec eng., this problem is called 'key debouncing.' When I type here at the keyboard, the keyboard device (or its driver) has to decide whether my keypresses that last tens of milliseconds ... practically forever! ... are supposed to be single keypresses or multiple presses or press-and-hold.

The usual way to solve the problem in software is to put a flag or timer on the key.

The flag system is tied to events: if the action is supposed to take place on a single keypress, then set a flag when the action starts and clear it when the action stops. Here's one possibility:

  1. class mywidget(Button):
  2. def __init__(self, master):
  3. ....
  4. self.bind('<KeyPress-b>', do_bleah)
  5. self.bind('<KeyRelease-b>',reset_bleah)
  6. self.reset_bleah() # must initialize the flag!
  7.  
  8. def print_bleah(self, event=None):
  9. if self.bleahOK:
  10. self.bleahOK = False
  11. self.set_up_bleah()
  12. # do other bleah-y stuff if needed
  13. else:
  14. self.continue_bleahing()
  15.  
  16. def reset_bleah(self, event=None):
  17. self.bleahOK = True

This way, the initial press sets up the action, but subsequent holding causes the action to continue. Basically, your function acts like two functions in one. It has one action on first keypress and a different action on key-holding.

You may recognize the flag as similar to a lock as used in threaded programs.

A second way to solve this for real-time systems (like pygame) is to set a timer of sorts:

  1. self.oldtime = 0
  2. do_bleah(self,event=None):
  3. if time.time() - self.oldtime > LONGENOUGH:
  4. self.oldtime = time.time()
  5. set_up_bleah()
  6. else:
  7. continue_bleahing()

Here, you impose a delay by setting oldtime when the button is first pressed and requiring that the next registered press be at least LONGENOUGH later.

IMO, this might be quirky in a system like Tkinter where the results of your keypress might not be finished when time is up. So I would probably go for the flag system with Tkinter and the timer system with something like pygame.

Jeff
Last edited by jrcagle; Feb 22nd, 2007 at 11:58 pm.
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 77
Reputation: aot is an unknown quantity at this point 
Solved Threads: 1
aot's Avatar
aot aot is offline Offline
Junior Poster in Training

Re: KeyPress event with holding down the key

 
0
  #4
Feb 23rd, 2007
Okay, I've been testing out your advice with my code. Maybe I'm being thick, but so far it's just not working. Here's what I've got:

  1. self.go = False
  2.  
  3. self.innerframe = Frame(frame)
  4. self.innerframe.bind('<a>', self.showJudgments)
  5. self.innerframe.bind('<KeyRelease-a>', self.makeChoice)
  6. self.innerframe.pack(expand=YES, fill=BOTH)
  7. self.innerframe.focus_force()
  8.  
  9. def showJudgments(self, event=None):
  10. if self.go == False:
  11. self.go = True
  12. self.showJudgmentsA()
  13. else:
  14. self.keepShowing()
  15.  
  16. def keepShowing(self):
  17. print 'a key being pressed'

Yet what happens when I hold the 'a' key is that both showJudgmentsA and makeChoice immediately get called over and over again, and keepShowing never gets called. I just don't get it.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: KeyPress event with holding down the key

 
0
  #5
Feb 24th, 2007
Odd. Here's a full working version:

  1. from Tkinter import *
  2.  
  3. class MyFrame(Frame):
  4.  
  5. def __init__(self, master):
  6. Frame.__init__(self, master)
  7. self.go = False
  8.  
  9. self.bind('<a>', self.showJudgments)
  10. self.bind('<KeyRelease-a>', self.makeChoice)
  11. self.pack(expand=YES, fill=BOTH)
  12. self.focus_force()
  13.  
  14. def showJudgments(self, event=None):
  15. if self.go == False:
  16. self.go = True
  17. self.showJudgmentsA()
  18. else:
  19. self.keepShowing()
  20.  
  21. def keepShowing(self):
  22. print 'a key being pressed'
  23.  
  24. def showJudgmentsA(self):
  25. print "key-press started"
  26.  
  27. def makeChoice(self, event=None):
  28. print "choice made"
  29. self.go = False
  30.  
  31.  
  32. mainw = Tk()
  33. mainw.f = MyFrame(mainw)
  34. mainw.f.grid()
  35. mainw.mainloop()

with output
  1. >>>
  2. key-press started # pressed 'a' here
  3. a key being pressed
  4. a key being pressed
  5. a key being pressed
  6. a key being pressed
  7. a key being pressed
  8. a key being pressed
  9. a key being pressed
  10. a key being pressed
  11. a key being pressed
  12. a key being pressed
  13. a key being pressed
  14. a key being pressed
  15. a key being pressed
  16. a key being pressed
  17. a key being pressed
  18. a key being pressed
  19. a key being pressed
  20. choice made # let go here
  21. key-press started # next press here
  22. a key being pressed
  23. a key being pressed
  24. a key being pressed
  25. a key being pressed
  26. a key being pressed
  27. a key being pressed
  28. a key being pressed
  29. a key being pressed
  30. a key being pressed
  31. choice made # ...and release.
  32. >>>
Hope it helps,
Jeff
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 77
Reputation: aot is an unknown quantity at this point 
Solved Threads: 1
aot's Avatar
aot aot is offline Offline
Junior Poster in Training

Re: KeyPress event with holding down the key

 
0
  #6
Feb 28th, 2007
Thanks for this. It must be that something is wrong with my setup because this code also doesn't work for me. When I run it, the frame flashes at a painfully visible rate, and nothing whatsoever happens when I press and release the 'a' key.

I'm using a Mac and the Eclipse IDE. I'll give it a try on my PC at home tonight, but I really do need this program to work on Macs, since that's what I have at work. Any thoughts?

P.S. Is there an easy way to copy/paste example code? Whatever I tried, I always ended up without tabbed spacing but with the unnecessary line numbers.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: KeyPress event with holding down the key

 
0
  #7
Feb 28th, 2007
Bummer! Macs aren't in my area, sorry to say. The unnecessary line numbers go away if you click the 'toggle plain text' widget underneath.

Can you get the individual events, '<a>' and '<KeyRelease-a>' to work correctly?

Jeff
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 77
Reputation: aot is an unknown quantity at this point 
Solved Threads: 1
aot's Avatar
aot aot is offline Offline
Junior Poster in Training

Re: KeyPress event with holding down the key

 
0
  #8
Mar 1st, 2007
Yep, by themselves they work fine.

Also, an update: I managed to get your example to work (I had to pack the frame instead of gridding it). However, my output is different:

  1.  
  2. key-press started
  3. choice made
  4. key-press started
  5. choice made
  6. key-press started
  7. choice made
  8. key-press started
  9. choice made
As you can see, my computer treats holding down the 'a' key as pressing and releasing it over and over (instead of just pressing it). As such, I don't really see a way to code what I want, as there's no way of determining what the final KeyRelease action is (unless there's some way of testing whether a key's been pressed in the last X milliseconds, then I could act only when it hasn't been, although there'd be a delay).

However, I've found an easy way out for now: it works fine with mouse button presses.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 3,956
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 917
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: KeyPress event with holding down the key

 
0
  #9
Mar 1st, 2007
Originally Posted by aot View Post
...
P.S. Is there an easy way to copy/paste example code? Whatever I tried, I always ended up without tabbed spacing but with the unnecessary line numbers.
For code enclosed in the [code=python] and [/code] tag pair, click on "Toggle Plain Text" so you can highlight and copy the code to your editor without the line numbers.

If I get this right, with the Mac OS a continuous key press is interpreted as a repeated key press/key release event pair?
Last edited by vegaseat; Mar 1st, 2007 at 6:47 pm. Reason: Mac
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: KeyPress event with holding down the key

 
0
  #10
Mar 1st, 2007
unless there's some way of testing whether a key's been pressed in the last X milliseconds, then I could act only when it hasn't been, although there'd be a delay
I think that'll be your winner. It'll be more of the timer method mentioned above rather than the flag method.

I'm surprised that the MacOS treats keypresses like this; could it be a feature of Tkinter for Macs? I'm curious enough that I'll post it on the Tkinter listserv and see what the pros know.

Jeff
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC