I am using Tkinter in python 3 to make a primitive game (I am aware of pyGame). My function that I have bound to KeyReleased is executed when any key is pressed. It seems to work just as KeyPress. Code down below
master.bind("KeyRelease",keyReleased) (with <> on the sides of KeyRelease
Most keyboards and OS's will send a steady stream of press/release events when you hold a key down. If you bind to <KeyRelease>, it absolutely will only fire on key release but your app may be betting multiple key release events, making it appear that they are happening on a press.
Related
I have problem controlling videos from Python 3.x using python-vlc bindings on Linux.
The video plays fine in a window, but hotkeys seem to be ignored. Does libvlc media player handle hotkeys?
My minimal code:
import vlc
from time import sleep
player = vlc.MediaPlayer("test.mp4")
player.video_set_key_input(True)
player.play()
while player.get_state()!=vlc.State.Ended:
sleep(1)
It is my belief that your contention, that video_set_key_input and video_set_mouse_input are the solution is a misunderstanding of those functions.
From vlc.py
def video_set_key_input(self, on):
'''Enable or disable key press events handling, according to the LibVLC hotkeys
configuration. By default and for historical reasons, keyboard events are
handled by the LibVLC video widget.
#note: On X11, there can be only one subscriber for key press and mouse
click events per window. If your application has subscribed to those events
for the X window ID of the video widget, then LibVLC will not be able to
handle key presses and mouse clicks in any case.
#warning: This function is only implemented for X11 and Win32 at the moment.
#param on: true to handle key press events, false to ignore them.
'''
return libvlc_video_set_key_input(self, on)
def video_set_mouse_input(self, on):
'''Enable or disable mouse click events handling. By default, those events are
handled. This is needed for DVD menus to work, as well as a few video
filters such as "puzzle".
See L{video_set_key_input}().
#warning: This function is only implemented for X11 and Win32 at the moment.
#param on: true to handle mouse click events, false to ignore them.
'''
return libvlc_video_set_mouse_input(self, on)
This suggests that setting those functions to False simply tells vlc that mouse and key input are to be ignored and passed to the users appliction.
For that to work, your application must be accepting and processing, mouse and key input coming out of the assigned X-window.
Not, that suddenly, pressing the space bar will pause the video, as when, vlc is performing the task of accepting and processing the mouse and key input.
I want some of my class functions to be called when a some keyboard keys are pressed, no matter which window is active. how to do that in LINUX. What I was using until now is OpenCV and waitKey() function but for that I need to show a window and have it active when pressing a keyboard key. I do have a main loop always running where the pressed key can be checked but it would be nice to have a solution where no loop is needed.
Is it possible to cleanly detect a key being held down in (ideally native) Python (2)? I'm currently using Tkinter to handle Keyboard events, but what I'm seeing is that when I'm holding a key down, Key, KeyPress, and KeyRelease events are all firing constantly, instead of the expected KeyPress once and KeyRelease at the end. I've thought about using the timing between events to try to differentiate between repeated firing and the actual event, but the timing seems inconsistent - thus, while doable, it seems like a pain.
Along the same lines, is there a nice way to detect multiple key presses (and all being held down?) I'd like to have just used KeyPress and KeyRelease to detect the start / end of keys being pressed, but that doesn't seem to be working.
Any advice is appreciated.
Thanks!
Use a keyup and keydown handler with a global array:
keys = []
def down(event):
global keys
if not event.keycode in keys:
keys.append(event.keycode)
def up(event):
global keys
keys.remove(event.keycode)
root.bind('<KeyPress>', down)
root.bind('<KeyRelease>', up)
Now you can check for multiple entries in keys. To remove that continuous behavior you described, you have to compare the previous state of keys after an event happens.
check the following link out :
[PyObjC Key Event Handling Question] Key Events Handling using PyObjC in Mac OS X
This was my initial question. I somehow managed to find a built-in plugin to solve the Key Event Management, but using Python. It is called Tkinter.
from Tkinter import *
root = Tk()
def screenshot(*ignore): os.system("screencapture -s %s" % check_snapshot)
root.bind('<Return>', greet)
root.mainloop( )
On pressing return (enter) key, it would successfully call screenshot function, and it would work.
Now, what I am looking for is, whenever I press combination of keys, like Command+Shift+4, the above function should be call.
This should be done in the same manner for Command+Shift+3 and Command+Shift+5 as well.
This should be done by checking which combination of keys are pressed, and accordingly, their respective screenshot functions should be called.
Also, this app shortcuts shouldn't be just relied on this app's window or frame, the window / frame of this window shouldn't be visible, yet, the shortcuts should work and trigger their respective functions.
root.withdraw()
This is the built-in function which hides the Tkinter window, but then, I am unable to invoke any of the functions. These functions only work on Tkinter window, or else, keys shortcuts don't work.
Any help would be appreciated.
Tkinter events only work when the tkinter window has focus,and for it to have focus it must be visible. You cannot use tkinter to handle events while another program is in the foreground.
The format of an event is <modifier-modifier-event-detail>, with modifier and event being optional. Event is something like KeyPress, ButtonPress, ButtonRelease and so on. Detail gives more detail, such as which key, or which button. For example, <ButtonRelease-1> is for releasing mouse button 1 (one).
Modifier is where you specify control, alt, delete or shift, and you can have more than one. Shift is a bit special, because it is often interpreted by the OS before tkinter ever sees is. So, for example, "Shift-3" on an American English keyboard is "#". Thus, instead of <Shift-3> you would use <#>.
Putting that all together, command-shift-3 would be <Command-#>. However, if you do that on a Mac, it will intercept that event and do a screenshot, so the binding will only work on Windows and Linux. On each OS there are a few key bindings you cannot override.
The best description of the format to use for specifying events is the tcl/tk man page on bind. Even though you're asking about tkinter, the underlying engine is tcl/tk.
I wrote a simple python script that gives control over the cursor to a joystick. My way to find out how this works is documented here. Now that works flawlessly but, as soon as I start the script to use the joystick, the mouse is useless, because my python routine sets the value back to its original, whenever a new joystick event comes in.
Thus I want my joystick events to be ignored as long as a key of the keyboard is pressed. I came across the pygame.key.get_pressed() method but this seems to work only, if the pygame window is in focus. I want this script running in background. Should I start using non-pygame events to listen to the keyboard or are there ways to keep track of the keyboard events analogue to the joystick events, which are recognized in background, via pygame?
I expect pygame sets up its own "sandbox" so that it's hard to detect input from outside its window. Your previous question indicates that you are also using the win32api module. We can use that to detect global key presses.
The correct way to detect key presses at the global scope is to set up a keyboard hook using SetWindowsHookEx. Unfortunately, win32api does not expose that method, so we'll have to use a less efficient method.
The GetKeyState method can be used to determine whether a key is down or up. You can continuously check the state of a key to see if the user has pressed or released it lately.
import win32api
import time
def keyWasUnPressed():
print "enabling joystick..."
#enable joystick here
def keyWasPressed():
print "disabling joystick..."
#disable joystick here
def isKeyPressed(key):
#"if the high-order bit is 1, the key is down; otherwise, it is up."
return (win32api.GetKeyState(key) & (1 << 7)) != 0
key = ord('A')
wasKeyPressedTheLastTimeWeChecked = False
while True:
keyIsPressed = isKeyPressed(key)
if keyIsPressed and not wasKeyPressedTheLastTimeWeChecked:
keyWasPressed()
if not keyIsPressed and wasKeyPressedTheLastTimeWeChecked:
keyWasUnPressed()
wasKeyPressedTheLastTimeWeChecked = keyIsPressed
time.sleep(0.01)
Warning: as with any "while True sleep and then check" loop, this method may use more CPU cycles than the equivalent "set a callback and wait" method. You can extend the length of the sleep period to ameliorate this, but the key detection will take longer. For example, if you sleep for a full second, it may take up to one second between when you press a key and when the joystick is disabled.
when your window gains or looses focus you get an ACTIVEEVENT. It's gain and state attributes tell you which state you've gained or lost. The easisest solution would probably be to catch this events in your main event loop and use them to keep track weather you have focus or not. Then you can just ignore joystick events if you don't have the focus.