防止 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=False
within时,程序再次调用了回调。由于没有连接时蓝牙连接的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 == True
和except:
时,回调被调用两次。
如果有人遇到更优雅的解决方案,那就太好了。
【问题讨论】:
activeBluetooth
属性在 App
类中的用途是什么?
Switch
的状态不会改变,除非你改变它。它不会自动切换回“真”。
嗨@John Anderson:activeBluetooth
只是作为试验的一部分,以防止在蓝牙连接未建立时开关更改值。我可以摆脱它。 2 分:想法是在蓝牙连接未建立时防止活动状态变为活动。即切换回active=False
为了防止on_active callback
内的状态改变。 (对不起格式,我一直在玩,我无法再次编辑评论)
您在kv
文件active: app.activeBluetooth
中的行设置了Switch
的active
属性和MainLoop
的activeBluetooth
属性之间的绑定。该绑定将调整Switch
的active
属性以与activeBluetooth
属性一致。我认为没有那个属性和绑定会更好。
【参考方案1】:
我刚刚意识到我认为是您的问题。 setBluetoothConnection()
中的 else
语句是 try, except, else
块的一部分。我认为您打算将else
与if
匹配。因此,您需要取消缩进 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 中的多个活动会话?