Kivy:如何限制同时接触?

时间:2017-02-14 18:55:06

标签: python python-3.x kivy

我使用的是Kivy 1.9.1和Python 3.5.2。在第一次完成处理之前触发多个触摸事件时,我的应用程序会中断。我正在寻找某种方法来限制给定时间的触摸事件数量为1(类似于HTML5引擎Phaser中的max_pointers属性)或过滤触摸事件并仅处理第一个事件。据我所知,触摸事件并不包含此信息。

我不相信我的代码的细节是相关的,但比抱歉更安全:

    def on_touch_down(self, touch):
        x, y = touch.x, touch.y
        x -= self.img_board.pos[0]
        y -= self.img_board.pos[1]
        if not (0 <= x <= self.img_board.size[0] and
                0 <= y <= self.img_board.size[1]):
            touch.ud['piece'] = None
            return

        file = int(x / self.square_size)
        rank = int(y / self.square_size)
        self.select((file, rank))
        piece = Board.instance.at_square(self.selected)
        touch.ud['piece'] = piece
        if piece:
            self.canvas.remove(piece.rect)
            self.canvas.after.add(piece.rect)

    def on_touch_move(self, touch):
        piece = touch.ud['piece']
        if piece:
            if Board.instance.to_move == piece.color:
                piece.rect.pos = (touch.x - piece.rect.size[0]/2,
                                  touch.y - piece.rect.size[1]/2)

    def on_touch_up(self, touch):
        piece = touch.ud['piece']
        if piece:
            self.canvas.after.remove(piece.rect)
            self.canvas.add(piece.rect)
            if Board.instance.to_move != piece.color:
                return

            x, y = touch.x, touch.y
            x -= self.img_board.pos[0]
            y -= self.img_board.pos[1]
            if not (0 <= x <= self.img_board.size[0] and
                    0 <= y <= self.img_board.size[1]):
                self.update_geometry()
                return

            dest = Board.an_from_tup( (int(x / self.square_size),
                                       int(y / self.square_size)) )
            if dest in piece.get_valid_moves():
                Board.instance.move(piece.position,dest)
                self.select(dest)
            self.update_geometry()

1 个答案:

答案 0 :(得分:0)

我能够通过创建TouchHandler小部件来实现这一点:

class TouchHandler(Widget):
    """ Non-display widget to handle touch order """
    instance = None

    def __init__(self):
        super().__init__()
        TouchHandler.instance = self
        self.active = None

然后在调用Window之前覆盖MyApp().run()的on_motion方法:

if __name__ == '__main__':
    # Ignore new touches before first touch has resolved
    TouchHandler()
    def on_motion(self, etype, me):
        if 'pos' in me.profile:
            if etype == 'begin':
                if not TouchHandler.instance.active:
                    TouchHandler.instance.active = me

    Window.bind(on_motion=on_motion)

    Window.size = (500,500)
    MyApp().run()

要实现这一点,您需要非常谨慎地管理触摸事件,并在TouchHandler.instance.active方法完成任务时将None重置为on_touch_up将使用触摸的小部件:

def on_touch_up(self, touch):
    if touch != TouchHandler.instance.active:
        return True # Signals Kivy to kill the event
    piece = touch.ud['piece']
    if piece:
        # ...
        self.update_geometry()
    TouchHandler.instance.active = None