2017-02-14 11 views
0

Я использую Kivy 1.9.1 и Python 3.5.2. Мое приложение ломается, когда перед первым завершается обработка более чем одного события касания. Я ищу способ ограничить количество событий касания в данный момент времени (что-то вроде атрибута max_pointers в движке HTML5 Phaser) или фильтровать события касания и обрабатывать только первый. Насколько мне известно, сенсорное событие не содержит эту информацию о себе.Kivy: Как ограничить одновременные привязки к одному?

Я не считаю, что специфика моего кода актуальны, но лучше перестраховаться, чем потом сожалеть:

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

ответ

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 «s on_motion до вызова MyApp().run():

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