2016-04-26 4 views
2

Я создаю приложение, использующее kivy. Поэтому я не думаю, что понимаю что-то правильно относительно поведения on_focus для FloatInput.Kivy - проблема с поведением TextInput on_focus

Позвольте мне вначале описать, что я пытаюсь сделать здесь. Я пытаюсь активировать всплывающее numpad, когда пользователь нажимает на TextInput (у этого numpad есть кнопки для цифр 0-9 и кнопка «enter»). Затем, как только пользователь выдает номер во всплывающем numpad и нажимает кнопку «enter», всплывающее окно должно закрываться, а текстовое поле TextInput должно быть обновлено до введенного пользователем номера.

Однако я столкнулся с проблемой. По сути, у меня есть форма с несколькими TextInputs, построенными, как описано выше (я буду называть их далее как «FloatInputs» b/c, это то, что я назвал ими). При первом вводе значений в один из FloatInputs все работает так, как ожидалось. Но проблема возникает, когда я пытаюсь ввести число во второй FloatInput. В частности, функция on_focus вызывается дважды как-то, и пользователь должен ввести значение в всплывающее окно дважды в результате (это, очевидно, не идеально, поскольку это может помешать пользователю).

Прошу прощения, если это глупый вопрос, но я был озадачен этим довольно долго. Я думаю, что суть проблемы заключается в том, что вы фокусируете TextInput и виджеты всплывающих окон, но я могу ошибаться. Если кто-то мог бы предложить предложения относительно того, как я могу исправить эту ошибку, я бы очень признателен ей.

Вот соответствующий код питона:

class FloatInput(TextInput): 

    def on_focus(self, instance, value): 

     print 'ON FOCUS CALLED - THIS SHOULD ONLY BE CALLED ONCE!' 

     # Adding this helped part of the problem (however, on_focus is still being called twice???) 
     self.unfocus_on_touch = False 

     prompt_content = BoxLayout(orientation='vertical')  # Main layout 

     num_pad = NumPadWidget() 
     prompt_content.add_widget(num_pad) 

     def my_callback(instance): 

      self.text = num_pad.ids.num_label.text 
      self.popup.dismiss() 

     # Now define the popup, with the content being the layout: 
     self.popup = Popup(id='num_pad_popup', title='Enter value', content=prompt_content, size_hint=(0.8,0.5), autodismiss=False) 

     num_pad.ids.enter_btn.bind(on_press=my_callback) 

     # Open the pop-up: 
     self.popup.open() 

А вот соответствующий код киловольт:

<[email protected]>: 
    font_size: '16dp' 
    bold: True 

<NumPadWidget>: 
    BoxLayout: 
     orientation: 'vertical' 
     BoxLayout: 
      size_hint_y: 1 
      id: num_label 
      Label: 
       id: num_label 
       text: '' 
     BoxLayout: 
      size_hint_y: 5 
      orientation: 'vertical' 
      BoxLayout: 
       NumPadButton: 
        text: '7' 
        on_press: 
         num_label.text = num_label.text + '7' 
       NumPadButton: 
        text: '8' 
        on_press: 
         num_label.text = num_label.text + '8' 
       NumPadButton: 
        text: '9' 
        on_press: 
         num_label.text = num_label.text + '9' 
      BoxLayout: 
       NumPadButton: 
        text: '4' 
        on_press: 
         num_label.text = num_label.text + '4' 
       NumPadButton: 
        text: '5' 
        on_press: 
         num_label.text = num_label.text + '5' 
       NumPadButton: 
        text: '6' 
        on_press: 
         num_label.text = num_label.text + '6' 
      BoxLayout: 
       NumPadButton: 
        text: '1' 
        on_press: 
         num_label.text = num_label.text + '1' 
       NumPadButton: 
        text: '2' 
        on_press: 
         num_label.text = num_label.text + '2' 
       NumPadButton: 
        text: '3' 
        on_press: 
         num_label.text = num_label.text + '3' 
      BoxLayout: 
       NumPadButton: 
        text: '0' 
        on_press: 
         num_label.text = num_label.text + '0' 
       NumPadButton: 
        text: '.' 
        on_press: 
         num_label.text = num_label.text + '.' 
       NumPadButton: 
        text: 'del' 
        on_press: 
         num_label.text = num_label.text[:-1] 
      BoxLayout: 
       BoxLayout: 
        size_hint_x: 1 
        NumPadButton: 
         text: 'C' 
         on_press: 
          num_label.text = '' 
       BoxLayout: 
        size_hint_x: 2 
        NumPadButton: 
         id: enter_btn 
         text: 'Enter' 
+0

Самое первое предложение должно заканчиваться TextInput, а не FloatInput. Прошу прощения за путаницу. – MV22

ответ

1

Хорошо после игры с этим немного больше я нашел решение для достижения функциональных возможностей, Я хотел. Однако, чтобы быть ясным, это действительно помогает понять, почему поведение on_focus действует так, как я описал в своем первоначальном посте.

Вот работа вокруг в случае, если кто интересуется:

class FloatInput(TextInput): 

    def __init__(self, **kwargs): 
     super(FloatInput, self).__init__(**kwargs) 

    def on_touch_down(self, touch): 
     if self.collide_point(touch.x, touch.y): 

      prompt_content = BoxLayout(orientation='vertical')  # Main layout 

      num_pad = NumPadWidget() 
      prompt_content.add_widget(num_pad) 

      def my_callback(instance): 
       self.text = num_pad.ids.num_label.text 
       self.popup.dismiss() 

      # Now define the popup, with the content being the layout: 
      self.popup = Popup(id='num_pad_popup', title='Enter value', content=prompt_content, size_hint=(0.8,0.5), autodismiss=False) 
      num_pad.ids.enter_btn.bind(on_press=my_callback) 

      # Open the pop-up: 
      self.popup.open() 

В частности, это решение работает с использованием on_touch_down вместо того, чтобы искать в фокусе TextInput. Кроме того, поиск столкновения с «if self.collide_point (touch.x, touch.y)» предотвращает ошибку, когда все виджеты того же типа реагируют на пользователя.

Надеюсь, это поможет кому-то!

+0

В последних сборках метод on_touch_down вызывается с двумя параметрами. Первый позиционный параметр (другой, а затем сам) является экземпляром объекта, на котором произошло касание. Где в качестве вторых параметров используется объект события касания. –

+0

Если вы потребляете событие касания, тогда вы должны вернуть True, чтобы прекратить распространение, я думаю. –

+0

Не могли бы вы предоставить полный рабочий код, чтобы я мог видеть функциональность, которую вы описываете? У меня есть аналогичная проблема и я хотел бы посмотреть, как она может интегрироваться с моим приложением. Благодарю. – Griff

0

У меня была аналогичная проблема при попытке вызвать модальный после нажатия на текстовый ввод. Если бы я попытался использовать on_focus, он выстрелил бы дважды. Для меня работала установка is_focusable = False и использование события on_touch_down для запуска функции.

Смежные вопросы