【问题标题】:Bind a button to a callback from Kivy to python将按钮绑定到从 Kivy 到 python 的回调
【发布时间】:2017-08-27 12:05:24
【问题描述】:

这几天我一直在努力解决这个问题。我使它仅在 Python 中工作(不使用 .kv 文件),但现在我无法弄清楚。

基本上,我将有一系列按钮来控制 Raspberry Pi 上的 GPIO。在仅 Python 的版本中,我有一个回调,其中包含一系列 IF,寻找正确的按钮“文本”以确定要激活的 pin。现在在 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 ==”标准?因为我的按钮上没有文字...

【问题讨论】:

    标签: python-3.x button callback kivy raspberry-pi3


    【解决方案1】:

    问题是,你在press_callback(obj) 中真正做的是检查 BoxLayout (ConsoleUI) 的状态,因为在这种情况下 objself 相同。如您所见,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()
    

    【讨论】:

    • 太棒了!感谢您提供非常完整的答案。我尝试了建议的代码,它有效!你摇滚!
    • @GroanMan 你很高兴 :)
    • @GroanMan 这将是公认的答案,还是您正在寻找其他答案?
    • 绝对!很抱歉
    • @GroanMan :D 不是那个意思。你自己决定哪一个是被接受的。只是想知道你是否想要别的东西。还有一个我回答了
    猜你喜欢
    • 2014-06-01
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2016-09-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    相关资源
    最近更新 更多