检测kivy textinput中的点击/触摸

max*_*mus 2 python user-interface kivy

我有一个textinput,我想在用户点击/触摸它时关注它.(相当标准!)它继承自DragableObject(kivy wiki中的用户示例)和GridLayout.

class DragableObject( Widget ):
    def on_touch_down( self, touch ):
        if self.collide_point( *touch.pos ):
            touch.grab( self )
            return True

    def on_touch_up( self, touch ):
        if touch.grab_current is self:
            touch.ungrab( self )
            return True

    def on_touch_move( self, touch ):
        if touch.grab_current is self:
            self.pos = touch.x-self.width/2, touch.y-self.height/2

class MyWidget(DragableObject, GridLayout):
    def __init__(self, **kwargs):
        kwargs['orientation'] = 'lr-tb'
        kwargs['spacing'] = 10
        kwargs['size_hint'] = (None, None)
        kwargs['size'] = (200, 80)

        self.cols = 2
        super(MyWidget, self).__init__(**kwargs)

        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=self.size)

        with self.canvas.before:
            Color(0, .5, 1, mode='rgb')

        self.bind(pos=self.update_rect)
        self.bind(size=self.update_rect)


        self.add_widget(Label(text='t1'))
        self.text1 = TextInput(multiline=False)
        self.add_widget(self.text1)
        self.add_widget(Label(text='t2'))
        self.text2 = TextInput(multiline=False)
        self.add_widget(self.text2)

        # these bind's don't seem to work
        self.text1.bind(on_touch_down=self.set_focus)
        self.text1.bind(on_touch_up=self.set_focus)
        self.text1.bind(on_touch_move=self.set_focus)


    def set_focus(self):
        print("pressed")
        self.text1.focus = True

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size
Run Code Online (Sandbox Code Playgroud)

我有两个问题.

一个.文本输入不可聚焦.

湾 我无法获得事件回调(例如on_touch_down)来处理textinput小部件.

有任何想法吗?

tot*_*ico 9

简答

你可以简单地使用一个Scatter.它包括拖动,旋转和缩放功能,您可以停用其中的任何一个或全部:

my_scatter = Scatter(do_rotation=False, do_scale=False) 
Run Code Online (Sandbox Code Playgroud)

你所描述的问题都不应该发生在 Scatter

答案很长

你的问题是,你要重写的on_touch_down,on_touch_moveon_touch_up父母的.

通常这些方法会调用相应的孩子.例如,当调用实例的on_touch_down方法时Widget,Widget实例将遍历其子on_touch_down节点,调用每个子节点的方法(如果您熟悉递归和树结构,我们正在谈论递归遍历方法 - 我认为预订 - 树遍历).

在DraggableObject类中重写此功能.你必须确保调用基类的方法:

super(DraggableWidget,self).on_touch_down(触摸)

根据您要查找的行为,方法可能如下所示:

(1)如果你总想给孩子打电话:

def on_touch_down( self, touch ):
    if self.collide_point( *touch.pos ):
        touch.grab( self )
    return super(DraggableWidget, self).on_touch_down(touch)
Run Code Online (Sandbox Code Playgroud)

(2)如果你只是想在没有碰撞时给孩子打电话:

def on_touch_down( self, touch ):
    if self.collide_point( *touch.pos ):
        touch.grab( self )
        return True      # Don't call the on_touch_down of the Base Class
    return super(DraggableWidget, self).on_touch_down(touch)
Run Code Online (Sandbox Code Playgroud)

还有更多的选择!返回值表示任何子节点是否处理了该事件.例如,您可以执行以下操作:

def on_touch_down( self, touch ):
    handled = super(DraggableWidget, self).on_touch_down(touch)
    if not handled and self.collide_point( *touch.pos ):
        touch.grab( self )
        return True
    return handled
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当其中一个子项处理事件时,您将避免拖动Widget.这一切都取决于你做了什么.