Open ensonic opened 9 years ago
How about this?
ev3_keys = [
'back' : ev3dev.button.back,
'left' : ev3dev.button.left,
'right' : ev3dev.button.right,
'up' : ev3dev.button.up,
'down' : ev3dev.button.down,
'enter' : ev3dev.button.enter
]
def key_pressed(k):
return ev3_keys[k].pressed()
def keys_pressed()
return [k for k in ev3_keys if ev3_keys[k].pressed()]
+1 for button.ev3_keys
, or maybe just button.keys
button.key_pressed(k)
is good.
maybe instead of button.keys_pressed
-> button.any_key_pressed()
(which would just check for keys_pressed()
not returning an empty list)
button.key_pressed(k) is good.
May be button.key[k].pressed()
is even better (where key
is a dict equal to ev3_keys
above).
maybe instead of button.keys_pressed -> button.any_key_pressed() (which would just check for keys_pressed() not returning an empty list)
Would not you miss an opportunity to do something like
if 'left' in buttons.keys_pressed(): do_something_great()
or even
if set(['left', 'up']).issubset(buttons.keys_pressed()): do_something_even_greater()
?
I don't think I'd miss them. For those I would probably rather write:
if buttons.left.isPressed(): go_left()
Given that there are just 6 keys, changes that two will be used for the same thing are probably quite low. We can also add both :)
Well, you could do
if set(['left', 'up']).issubset(buttons.keys_pressed()): go_north_west()
:)
Ok, I'll try to add this into python bindings.
Should be fixed by ddemidov/ev3dev-lang-python@f535ed6c5201f4af035d0adc4e4b2fb3011c20db and ddemidov/ev3dev-lang-python@3e1a70a686771b4bd4a92220c91075f6b163e223.
Thanks!
@ensonic / @ddemidov - I am about to merge in the helper functions for the Button
API, but @ddemidov's changes are specific to the EV3. I have 2 questions:
Button
now that we have a cache for the file descriptor?any_pressed()
function return None
or an iterable list of pressed keys?@ensonic - can you send along some sample code where you are using the Button
API today, and where the helpers are used? The Button
properties as lower case, like this:
if b.up:
....
if b.backspace:
....
- Will the helpers still work as implemented [here][ddemidov/ev3dev-lang-python@f535ed6] without instantiating a Button now that we have a cache for the file descriptor?
Probably not. The properties (up
, down
, etc) used to be instances of Button
class, so there was no need instantiating the main class (it was used simply as namespace). But it should be easy to reimplement the helper functions with getattr()
.
- Should the any_pressed() function return None or an iterable list of pressed keys?
I think @ensonic and I agreed that any_pressed()
should return boolean value.
can you send along some sample code where you are using the Button API today?
I am not @ensonic, but this looks like what you are looking for: https://mp-devel.iais.fraunhofer.de/code/projects/ORA/repos/robertalab/browse/EV3MenuEv3dev/roberta/ev3.py#187
If any_pressed()
returns True
what you typically end up doing is enumerating the buttons to find out which one is pressed :-) I'd still like a helper to return a list of pressed buttons - maybe list_pressed()
?
Looking at @ensonic's code, the important bits for the Button
API seem to be:
self.key = ev3dev.button
...
# key
def isKeyPressed(self, key):
if key in ['any', '*']:
# TODO: https://github.com/ev3dev/ev3dev-lang/issues/108
for key in ['up', 'down', 'left', 'right', 'enter', 'back']:
if getattr(self.key, key).pressed:
return True
else:
return False
else:
# remap some keys
keys = {
'escape': 'back',
'backspace': 'back',
}
if key in keys:
key = keys[key]
# throws attribute error on wrong keys
return getattr(self.key, key).pressed
def isKeyPressedAndReleased(self, key):
return False
And it's pretty clear that he's looking for an "any" operation with Boolean result. I'm going to add the helpers to the autogen
template for the button properties because that way the platform specific list can be generated easily.
If any_pressed() returns True what you typically end up doing is enumerating the buttons to find out which one is pressed :-) I'd still like a helper to return a list of pressed buttons - maybe list_pressed()?
I agree that could be helpful.
Just confirming, I was indeed looking for something that returns true if any key is pressed. That is useful when e.g. showing an error.
That's b.any
- if you want the list of buttons that are pressed, b.buttons_pressed
and if you want to check if a particular set of buttons is pressed, then b.check_buttons([...])
But I realize there's a bug - if there are more buttons pressed than specified. I'll fix that...basically we want all the buttons pressed to match all the buttons specified. and passing an empty list will return True
if no buttons are pressed.
I've read through the updates here but I'm unsure about how the current Button class works. What is the current notation for checking for a button press? I read the documentation on readthedocs but am not sure if that is updated. So if I want to check for whether the left button is pressed or not, should I write
b.left
, ev3.Button.left
(if I have ev3dev imported as 'ev3'), or getattr(ev3dev.buttons, 'left').pressed
? Thank you!
Currently you have to create an instance of the Button
class and use it to query button states:
btn = ev3.Button()
# Is 'Left' button pressed?
print('yes' if btn.left else 'no')
# Check if any buttons are pressed:
print('yes' if btn.any() else 'no')
# Do something when state of 'Left' button changes:
def report(state):
print('pressed' if state else 'not pressed')
btn.on_left = report
while True: # This loop checks buttons state continuously, calls appropriate event handlers
btn.process()
@ddemidov - Thank you. This is exactly what I was looking for. The button class makes much more sense now. Edit: And my code is now up and running correctly.
I am missing two feature from the button api.
1) if I want to check if a key is pressed, where key is a variable I have to do:
This is not very discoverable.
2.) how would I check for any key pressed? If there would be an enum of available keys, I could check if any of them are pressed. We could also just have some convenience api for this.