2016-04-02 14 views
3

Ich habe ein paar Widgets und möchte sie "ziehen und auswählen". Ich verwende ein Auswahl-Widget als Rechteck, um die Auswahlgröße anzuzeigen, und verwende dann for child in root.children: selection.collide_widget(child). Das funktioniert so lange, wie ich von links unten nach rechts oben ziehe, weil die Größe der Auswahl-Widgets dann positiv ist.collide_widget mit negativer Größe

Wird erwartet, dass Widgets mit negativer Größe nicht mit collide_widget funktionieren?

Sollte ich negative Größen überhaupt nicht für Widgets verwenden?

kv-Datei:

<SelectionBox>: 
    size: 0,0 
    size_hint: None, None 
    canvas: 
     Color: 
      rgba: 1, 1, 1, 0.1 
     Rectangle: 
      pos: root.pos 
      size: root.size 

<Selectable>: 
    size: 32, 32 
    size_hint: None, None 
    canvas: 
     Color: 
      rgba: 0, 1, 0, 1 
     Rectangle: 
      pos: root.pos 
      size: root.size 

Code:

class Selectable(Widget): 
    pass 

class Canvas(FloatLayout): 

    touch_down = False 

    def on_touch_down(self, touch): 
     self.selection = sel = SelectionBox() 
     sel.pos = touch.pos 
    self.touch_down = True 
     self.add_widget(sel) 

    def on_touch_move(self, touch): 
     if self.touch_down: 
#~~~~~~~~~~~~~~~~~~~~~~~~~ Interesting line here ~~~~~~~~~~~~~~~~~~~~~~~~~ 
      # size can get negative 
      self.selection.size = (touch.pos[0] - self.selection.pos[0] , touch.pos[1] - self.selection.pos[1]) 

    def on_touch_up(self, touch): 

     for widget in self.children: 
      if widget is self.selection: 
       print("Children is selection") 
      if self.selection.collide_widget(widget): 
      print("Widget collides: {}".format(widget)) 

     self.touch_down = False 
     self.remove_widget(self.selection) 

canvas = Canvas() 

class MyApp(App): 
    def build(self): 
     canvas = Canvas() 
    for i in range(0,11): 
     sel = Selectable() 
     sel.pos = random.random() * 1000, random.random() * 1000 
     self.add_widget(sel) 
     return canvas 

if __name__ == "__main__": 
    MyApp().run() 

Antwort

1

der Tat ist dieses Verhalten erwartet wird. Von kivy.uix.widget.Widget:

def collide_widget(self, wid): 
    if self.right < wid.x: 
     return False 
    if self.x > wid.right: 
     return False 
    if self.top < wid.y: 
     return False 
    if self.y > wid.top: 
     return False 
    return True 

Für eine negative Größe, diese Logik wird nicht funktionieren, wie z.B. self.right < self.x. Eine einfache Abhilfe wäre collide_widget für diese Klassen neu zu definieren, wobei negative Größen zu erwarten sind:

def collide_widget(self, wid):  
    if max(self.x, self.right) < min(wid.x, wid.right): 
     return False 
    if min(self.x, self.right) > max(wid.x, wid.right): 
     return False 
    if max(self.top, self.y) < min(wid.y, wid.top): 
     return False 
    if min(self.top, self.y) > max(wid.y, wid.top): 
     return False 
    return True 

Diese kümmert sich um beide Widgets (die eine collide_widget und derjenige getestet Aufruf) mit positiven oder negativen Größen.

Ich bin mir jedoch nicht sicher, ob der Code woanders auf negativen Größen beruht, die nicht wie erwartet zusammenstoßen (also affe-patch auf Widget mit Vorsicht).

Verwandte Themen