Запретить активное изменение статуса при обратном вызове on_active - PullRequest
1 голос
/ 07 июня 2019

Моя цель

В моем приложении Kivy для Android у меня есть виджет «Переключатель», который при подключении создает соединение через разъем Bluetooth.При выключении закрывает сокет.Обратный вызов выполняется с параметром on_active.

Идея состоит в том, что при включении обратный вызов проверяет, было ли установлено соединение.Если да, то переключатель меняет свое значение.Если нет, появляется всплывающее окно, и переключатель возвращается к значению «active = False».

Моя проблема в том, что я не могу предотвратить изменение виджета Switch на «Active = True», когдаСоединение Bluetooth не установлено.

Вопрос : возможно ли предотвратить изменение статуса «Активный» внутри обратного вызова «on_active»?

Я смотрел вдокументация и много других примеров в интернете, но безуспешно.Я новичок в kivy / python, и любая помощь будет высоко ценится.

Уже пробовал

  1. Я пытался связать свойство active с переменной приложенияпетля.Этот подход работает с другими кнопками, но при вызове в обратном вызове on_active активное состояние не изменяется.Кажется, что значение связанной переменной не обновляется (от False до True), пока обратный вызов не будет завершен.Поэтому я не могу использовать этот подход, потому что "app.activeSwitch = False" позже отменяется действием обратного вызова

  2. Другой подход, который я также попытался, - передать указательПереключатель "(я думаю, называется указателем) для обратного вызова, а затем изменить статус через него.При таком подходе происходит сбой приложения.

  3. Я думал об использовании Clock.schedule_once с таймером или перед следующим кадром, но это плохое решение.

  4. Моей последней мыслью было попытаться прервать обратный вызов или использовать «return False», но это не сработало.

Основы кода

Kv File

    <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, у меня естьвыяснил, что делает мою программу сбой.Ниже приведено решение проблемы, но все же это не очень элегантное решение :

- Проблема : при определении activeSwitch.active=False в пределах on_active callback , программа снова вызвала обратный вызов.Поскольку переменная socket соединения bluetooth не существует, когда нет соединения, я вызывал несуществующую переменную.

Обходное решение

Файл 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: введено.

Чтобы знать, было бы здорово, если бы кто-то нашел более элегантное решение.

1 Ответ

0 голосов
/ 08 июня 2019

Я только что понял, что я думаю, это ваша проблема.Ваш оператор else в setBluetoothConnection() действует как часть блока 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...