Kivy TextInput on_焦点行为问题

2024-09-27 00:13:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用kivy创建一个应用程序。所以我认为我对FloatInput的on-focus行为理解不正确。在

让我先描述一下我在这里要做的事情。当用户点击TextInput时,我试图激活一个弹出的numpad(这个numpad只有数字0-9的按钮和一个“enter”按钮)。接下来,一旦用户在弹出的numpad中提供了一个数字并点击了“enter”按钮,弹出窗口应该关闭,TextInput的文本字段应该更新为用户输入的数字。在

但是,我遇到了一个问题。本质上,我有一个表单,上面描述了多个TextInputs(我在后面将它们称为“FloatInputs”b/c,这就是我命名它们的原因)。第一次在FloatInputs中输入值时,一切都按预期工作。但每当我试图在第二个FloatInput中输入一个数字时,问题就会出现。具体来说,on_focus函数会以某种方式调用两次,因此用户必须在弹出窗口中输入两次值(这显然不理想,因为这会使用户感到沮丧)。在

如果这是一个愚蠢的问题,我很抱歉,但我已经困惑了好一阵子了。我认为问题的核心在于TextInput和弹出窗口小部件的关注顺序,但我可能错了。如果有人能提供我如何修复这个错误的建议,我将不胜感激。在

下面是相关的python代码:

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()

以下是相关的kv代码:

^{pr2}$

Tags: the用户selfon数字textinputcontent按钮
3条回答

确保所有的textInput(在您的示例中为“FloatInput”)在代码中尽快将widget属性unfocus_-on-touch设置为False。这意味着在一个kv文件中,factory builder字符串(如下)或一些包装的__init__类函数。在on_focus事件中设置此属性太晚,可能会导致它被触发两次。在

Builder.load_string('''
<RootWidget>:
    TextInput:
        unfocus_on_touch: False
        id: id_textbox
        text: 'hello world'
        multiline: False
        font_size: 20
''')

好吧,在玩了一点,我找到了一个解决方案,以实现我想要的功能。不过,要弄清楚这一点确实解决了为什么专注行为会以我在我最初的帖子中描述的方式进行。在

如果有人感兴趣,这里有一个解决办法:

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,而不是寻找文本输入的焦点。另外,寻找与“if”的碰撞自碰撞点(touch.x,touch.y)“防止同一类型的所有小部件响应用户触摸的错误。在

我希望这对某人有帮助!在

我也有类似的问题,当我试图调用一个模态后,点击一个文本输入。如果我尝试使用on_focus,它将触发两次。对我有效的方法是设置is_focusable = False并使用on_touch_down事件来启动函数。在

相关问题 更多 >

    热门问题