防止 on_active 回调中的活动状态更改

Posted

技术标签:

【中文标题】防止 on_active 回调中的活动状态更改【英文标题】:Prevent active status change in on_active callback 【发布时间】:2019-10-22 22:23:17 【问题描述】:

我的目标

在我的安卓 Kivy 应用程序中,我有一个 Switch 小部件,它在打开时会创建一个蓝牙套接字连接。关闭时,它会关闭套接字。回调使用 on_active 选项执行。

这个想法是,当打开时,回调会检查连接是否已经建立。如果是,则开关更改其值。如果否,则会出现一个弹出窗口,并且开关会返回“active=False”值。

我的问题是当蓝牙连接未建立时,我无法阻止 Switch 小部件更改为“Active=True”。

问题:是否可以在“on_active”回调中阻止“Active”状态更改?

我在 Internet 上查看了文档和许多其他示例,但没有成功。我是 kivy/python 的新手,任何帮助将不胜感激。

已经尝试过

    我已尝试将 active 属性绑定到 App 循环的变量。此方法适用于其他按钮,但在“on_active”回调中调用时,活动状态不会改变。 似乎绑定变量值在回调完成之前不会更新(从 False 到 True)。因此,我不能使用这种方法,因为“app.activeSwitch=False”稍后会被回调操作否决

    我也尝试过的另一种方法是将“开关指针”(我认为称为指针)传递给回调,然后通过它更改状态。应用会因这种方法而崩溃。

    我曾想过在计时器或下一帧之前使用 Clock.schedule_once,但这是一个糟糕的解决方案。

    我最后的想法是尝试中断回调或使用“return False”,但没有奏效。

代码基础

Kv 文件

    <ClassName>:
        BoxLayout:
          Switch:
             on_active: app.setBluetoothConnection(self.active)
              active: app.activeBluetooth

Python 文件:

 class MainLoop(App):
    activeBluetooth=BooleanProperty(False)

    #Here comes build with other Widget building and callbacks

    def setBluetoothConnection(self,activeValue):
      if activeValue == True:
          try:
                #Check whether we can connect and stablish connection
          except:
                #Error-Popup                        
                popup = Popup(content=content, title='Connection,error',size_hint=(None, None), size=(300, 300))
                popup.open()

                #What can I define here to prevent the active status change of the switch?#

           else:
                #Close the socket connection and other stuff

总结

我认为必须有一个非常简单的解决方案来解决这个问题,而无需更改大量代码......

非常感谢任何帮助或建议。

更新问题

感谢@John Anderson 的建议/提示,我已经弄清楚是什么导致我的程序崩溃。以下是该问题的解决方案,但仍然不是一个非常优雅的解决方案

-问题:当在on_active回调中定义activeSwitch.active=Falsewithin时,程序再次调用了回调。由于没有连接时蓝牙连接的socket变量不存在,所以我调用了一个不存在的变量。

解决方法

kv 文件

  <ClassName>:
        BoxLayout:
          Switch:
             on_active: app.setBluetoothConnection(self)
              active: False

Python 文件:

 class MainLoop(App):
    #Here comes build with other Widget building and callbacks

    def setBluetoothConnection(self,activeSwitch):
      if activeSwitch.active == True:
          try:
                self.recv_stream, self.send_stream, self.socket = get_socket_stream('connectionBluetooth')   #DIALOG-SPS
          except:
                #Error-Popup                        
                popup = Popup(content=content, title='Connection,error',size_hint=(None, None), size=(300, 300))
                popup.open()

                activeSwitch.active=False

       else:
           try:
                self.socket.close() #close the socket connection

           except:
                pass

以下代码是解决问题的方法,但它不是最佳的,因为当输入if activeSwitch.active == Trueexcept: 时,回调被调用两次

如果有人遇到更优雅的解决方案,那就太好了。

【问题讨论】:

activeBluetooth 属性在 App 类中的用途是什么? Switch 的状态不会改变,除非你改变它。它不会自动切换回“真”。 嗨@John Anderson:activeBluetooth 只是作为试验的一部分,以防止在蓝牙连接未建立时开关更改值。我可以摆脱它。 2 分:想法是在蓝牙连接未建立时防止活动状态变为活动。即切换回active=False 为了防止on_active callback内的状态改变。 (对不起格式,我一直在玩,我无法再次编辑评论) 您在kv 文件active: app.activeBluetooth 中的行设置了Switchactive 属性和MainLoopactiveBluetooth 属性之间的绑定。该绑定将调整Switchactive 属性以与activeBluetooth 属性一致。我认为没有那个属性和绑定会更好。 【参考方案1】:

我刚刚意识到我认为是您的问题。 setBluetoothConnection() 中的 else 语句是 try, except, else 块的一部分。我认为您打算将elseif 匹配。因此,您需要取消缩进 else 块。将Switch 实例传递给setBluetoothConnection() 而不仅仅是active 值会简化您的代码:

kv:

<ClassName>:
    BoxLayout:
      Switch:
         # pass the Switch instance to the setBluetoothConnection() method
         on_active: app.setBluetoothConnection(self)
         active: False

python 代码:

 class MainLoop(App):
    #Here comes build with other Widget building and callbacks

    def setBluetoothConnection(self,switch_instance):
      if switch_instance.active == True:
          try:
                #Check whether we can connect and stablish connection
          except:
                #Error-Popup                        
                popup = Popup(content=content, title='Connection,error',size_hint=(None, None), size=(300, 300))
                popup.open()

                #What can I define here to prevent the active status change of the switch?#

       # note the indentation matches the above `if` statement
       else:
            #Close the socket connection and other stuff
            switch_instance.active = False

【讨论】:

嗨@John。谢谢您的回答。 else 缩进只是我发布的代码中的一个错误:它在应用程序中正确编写。但是,多亏了您的建议,我对代码有了一点了解,并且找到了解决方法。请检查原帖中的问题更新

以上是关于防止 on_active 回调中的活动状态更改的主要内容,如果未能解决你的问题,请参考以下文章

Swift 防止 TabBar 在键盘处于活动状态时向上移动

如何在不影响密码更改行为的情况下正确防止 ASP.NET Identity 2.2.1 中的多个活动会话?

没有输入数据时,如何防止 GROUP_CONCAT 创建结果?

Angular 和引导 UI 选项卡都变为活动状态以防止默认

如何防止 Ajax 调用使会话保持活动状态?

如何防止在方向更改时重新创建片段寻呼机中的片段?