如何在类或函数中使用 gpiozero.Button.when_pressed

问题描述

我在气象站 (raspBerry pi) 工作,我正在使用 python。我开发了一个正在运行的程序,但现在我决定更新我的代码并构建所有内容(创建类等)。 但是现在我遇到了两个关于 gpiozero Button 的问题。
首先,当我尝试将一个函数分配给 Button.when_pressed 函数或类中,当按钮被按下时该函数不会被调用

以下代码只是一个示例,以尽可能减少代码

from gpiozero import Button
import time

number = 0
def function_that_gets_called():
    global number
    number += 1

def main():
    wind_sensor = Button(6)
    wind_sensor.when_pressed = function_that_gets_called

main()

while True:
    # Sleep,so the program doesn't exit immediately
    time.sleep(60)
    

# Do some other stuff with number

为什么在按下 Button 时没有调用 function_that_gets_called。同样,当我尝试在类中分配 when_pressed 时,它也不起作用。

其次,为什么我必须使用 global number?否则数字变量不会改变,但有没有其他更好的解决方案?

非常感谢!

编辑:编辑 time.sleep(60)。我指定了,我所说的不起作用。这是我在 stackoverflow 上的第一个问题,所以如果不准确,请原谅,告诉我如何改进我的问题会很棒。

解决方法

我不确定当您调用 main() 后主函数退出时,wind_sensor 会发生什么情况。我的猜测是它会被摧毁。无论如何,如果您删除 main 和对它的调用,您的代码将起作用。尝试在增加 print(number) 后添加它,以便在您按下按钮时可以看到一些内容

关于这个类...

我在课堂上的 when_pressed 也遇到了这个问题。但我已经让它在我的情况下工作。 我的应用程序可以有可变数量的按钮,它们都由在代码开头实例化的对象进行管理。应用程序不会退出,因为有一个带有 ws.runForever() 的底层 websocket 客户端。在你的情况下,你可以使用一个循环 while 1: pass 这将使用大约 12% 到 15% 的 CPU 或 pause() 来保持代码运行,而不使用处理器(使用 ctrl+c 退出)

现在我使用 dict 来处理位于我的类中的变量 nº 按钮,以及我的处理程序。 像这样的东西可以使用类,继续运行,您可以扩展代码以获得动态数量的按钮。

from gpiozero import Button
import json

class myController()
   theButtons={}
   yourNumber=0

   def __init__(self):
      self.yourNumber=0 #here is the right place to initialize the variables!

   def handler(self,Button): # here the first parameter is the class itself and then the button that generated the interrupt --> this works like that,but could not confirm that self needs to exist before the mandatory arg "Button" because it is inside the class,or by other reason. Can somebody confirm? not clear in documentation.
      print("Pressed button in pin: ",str(Button.pin.number))
      self.yourNumber +=1
   
   def addButton(msg): # Example json: '[{"id":"button1","pin":2},{"id":"button2","pin":4}]' the msg is the message that is received via websocket with the configuration of buttons. you can make it at you own needs. id and pin are string that I choose for machines dialog
      btns=json.loads(msg)
      for b in btns:
         theButtons[b.get('id')]=Button(b.get('pin'))
         theButtons[b.get('id')].when_pressed=self.handler 

#and that's it for the class no let's instantiate and make the code persist running

if __name__ == "__main__": # this is executed only if you call this file. if you use it as import it will not run. it's a best practice,should you need to import the class in other file and don't want the code to execute. 
   btnController=myController() 
   pause()

类在这个用例上有点矫枉过正,但我​​相信它可以在不使用全局变量的情况下解决您的问题。