将按钮绑定到从 Kivy 到 python 的回调
Bind a button to a callback from Kivy to python
几天来我一直在努力解决这个问题。我让它在 Python 中工作(不使用 .kv 文件),但现在我无法弄清楚。
基本上,我会有一系列按钮来控制 Raspberry Pi 上的 GPIO。在仅 Python 版本中,我有一个回调,其中包含一系列 IF 寻找正确的按钮 "text" 以确定要激活的引脚。现在在 kivy 版本中,我把它简化为一个按钮,将回调移动到代码中的许多地方,等等,但似乎没有任何效果。
这是 pyton 代码:
# Set up GPIO:
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
defrost = 27
GPIO.setup(defrost, GPIO.OUT)
GPIO.output(defrost, GPIO.LOW)
class ConsoleUI(BoxLayout):
def press_callback(obj):
if obj.state == "down":
GPIO.output(defrost, GPIO.HIGH)
else:
GPIO.output(defrost, GPIO.LOW)
pass
class ConsolesimpleApp(App):
def build(self):
return ConsoleUI()
if __name__ == '__main__':
ConsolesimpleApp().run()
GPIO.cleanup()
这是 KV 代码:
# Console.kv
<ConsoleUI>:
ToggleButton:
id: Defrost
on_press: root.press_callback()
Image:
source: 'rear-window-defrost.png'
以及当前的错误信息:
AttributeError: 'ConsoleUI' object has no attribute 'state'
谢谢大家指点!
额外问题:为每个按钮设置不同的回调是更好的形式还是 "if obj.text ==" 标准?因为我的按钮上没有文字...
问题是,您在 press_callback(obj)
中真正做的是检查 BoxLayout (ConsoleUI
) 的状态,因为 obj
在这种情况下与说 self
。如您所见,boxlayout 没有任何状态属性。
所以你真正想做的是检查切换按钮的状态。幸运的是你已经给了它一个 id,所以试着像这样改变你的方法:
def press_callback(self):
if self.ids.Defrost.state == "down":
GPIO.output(defrost, GPIO.HIGH)
else:
GPIO.output(defrost, GPIO.LOW)
并回答你的奖励问题。
您可以将内容传递给回调。所以我会传递按钮本身和密码。现在你其实可以忘记我上面说的了
尝试 运行 这个小例子,看看我的意思:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<ConsoleUI>:
ToggleButton:
on_press: root.press_callback(self,1)
ToggleButton:
on_press: root.press_callback(self,2)
ToggleButton:
on_press: root.press_callback(self,3)
''')
class ConsoleUI(BoxLayout):
def press_callback(self,button,pin):
if button.state == "down":
print("pin {} goes high".format(pin))
else:
print("pin {} goes low".format(pin))
class ConsolesimpleApp(App):
def build(self):
return ConsoleUI()
if __name__ == '__main__':
ConsolesimpleApp().run()
几天来我一直在努力解决这个问题。我让它在 Python 中工作(不使用 .kv 文件),但现在我无法弄清楚。
基本上,我会有一系列按钮来控制 Raspberry Pi 上的 GPIO。在仅 Python 版本中,我有一个回调,其中包含一系列 IF 寻找正确的按钮 "text" 以确定要激活的引脚。现在在 kivy 版本中,我把它简化为一个按钮,将回调移动到代码中的许多地方,等等,但似乎没有任何效果。
这是 pyton 代码:
# Set up GPIO:
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
defrost = 27
GPIO.setup(defrost, GPIO.OUT)
GPIO.output(defrost, GPIO.LOW)
class ConsoleUI(BoxLayout):
def press_callback(obj):
if obj.state == "down":
GPIO.output(defrost, GPIO.HIGH)
else:
GPIO.output(defrost, GPIO.LOW)
pass
class ConsolesimpleApp(App):
def build(self):
return ConsoleUI()
if __name__ == '__main__':
ConsolesimpleApp().run()
GPIO.cleanup()
这是 KV 代码:
# Console.kv
<ConsoleUI>:
ToggleButton:
id: Defrost
on_press: root.press_callback()
Image:
source: 'rear-window-defrost.png'
以及当前的错误信息:
AttributeError: 'ConsoleUI' object has no attribute 'state'
谢谢大家指点!
额外问题:为每个按钮设置不同的回调是更好的形式还是 "if obj.text ==" 标准?因为我的按钮上没有文字...
问题是,您在 press_callback(obj)
中真正做的是检查 BoxLayout (ConsoleUI
) 的状态,因为 obj
在这种情况下与说 self
。如您所见,boxlayout 没有任何状态属性。
所以你真正想做的是检查切换按钮的状态。幸运的是你已经给了它一个 id,所以试着像这样改变你的方法:
def press_callback(self):
if self.ids.Defrost.state == "down":
GPIO.output(defrost, GPIO.HIGH)
else:
GPIO.output(defrost, GPIO.LOW)
并回答你的奖励问题。
您可以将内容传递给回调。所以我会传递按钮本身和密码。现在你其实可以忘记我上面说的了
尝试 运行 这个小例子,看看我的意思:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<ConsoleUI>:
ToggleButton:
on_press: root.press_callback(self,1)
ToggleButton:
on_press: root.press_callback(self,2)
ToggleButton:
on_press: root.press_callback(self,3)
''')
class ConsoleUI(BoxLayout):
def press_callback(self,button,pin):
if button.state == "down":
print("pin {} goes high".format(pin))
else:
print("pin {} goes low".format(pin))
class ConsolesimpleApp(App):
def build(self):
return ConsoleUI()
if __name__ == '__main__':
ConsolesimpleApp().run()