I'm trying to make a dual use of 1 button: first use ( short press ) to exectute function "A", a second use ( long press ) to execute function "B".

function A is executed after button1.when_pressed = fucntion_a function B is execute as follows: button1.hold_time=3 button1.when_held= function_b

But- when a long press is done, it runs function_a prior to function_b ( the intention is to execute function_b only.

  • You are using the wrong tool. What you want to do is possible, but you need to delay the execution of function_a until after the possibility of function_b. Computer programs still need to obey the laws of causation.
    – Milliways
    Jun 30 '17 at 12:18
  • Was hopping for a better way :( can you be more specific ? ( i was thinking of placing a time.sleep if condition in function_a ... is this the right way ??)
    – guyd
    Jun 30 '17 at 12:22
  • I am reluctant to propose a solution, I only use Python when there is some advantage e.g. list or dictionary processing, and normally use c. sleep in any function is usually bad news; I would detect button press, record time then re-test regularly and check duration, but without a specification of what you are trying to achieve any solution would be premature.
    – Milliways
    Jun 30 '17 at 12:33
  • This is covered in the FAQ: gpiozero.readthedocs.io/en/stable/… Apr 10 '19 at 13:24

A simpler solution would be to use button1.when_released = fucntion_a. Then function a only has to determine if function b executed by checking the button's held_time property.

  • When I tried this, held_time was set to None in function a whether long pressed or not. Function b did execute. I suspect held_time is cleared after function b exits. I solved it by using a global variable to hold the state of whether it was long pressed or not. Function b sets that to True; function a checks it and also sets it back to False. There's probably a better way, but this worked for me Feb 7 '18 at 5:25

This seems to be working for me:

from gpiozero import Button
from time import sleep

aBtn = Button(6)
bBtn = Button(13, pull_up=False)

def buTest(but):
    sleep(0.5) #adjust to your liking
    act = but.is_active
    if act:
        # long press action here
        print('Button {} long press'.format(str(but.pin)))
        #short press action here
        print('Button {} short press'.format(str(but.pin)))

aBtn.when_pressed = buTest
bBtn.when_pressed = buTest

Button aBtn is connected to GND and pin 6 and pulled up by default

Button bBtn is connected to +3.3V and pin 13 and pulled down


As suggested in previous comment- I solved it like this:

def push_button():

    while button1.is_active and (diff <hold_time) :

    if diff < hold_time :

https://gpiozero.readthedocs.io/en/stable/faq.html#how-do-i-use-button-when-pressed-and-button-when-held-together This is how it's supposed to work, but it doesn't work. First of all, you have to add in something like pause() to keep the function running. But even with that, the logic used as an example there doesn't reliably trigger only the held or pressed function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.