2015-01-05 3 views
0

Nykakin이 제공하는 답변 here에서 코드를 확장하려고합니다. 위젯은 Kivy에서 동적으로 정의되고 ID가 동적으로 할당 된 다음 ID를 기반으로 조작됩니다.Kivy : 업데이트 함수에서 동적으로 생성 된 위젯 조작하기

'최종 게임'은 ID를 기반으로 위젯의 위치를 ​​변경하여 몇 가지 기본 2D 물리를 구현하는 것입니다.

위젯 트리를 업데이트 기능 (오류 인라인)에서 '걸을 수 없습니다'.

그런 일을 할 수 있습니까? 내 용어가 잘못된 경우

#code begins here 
from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.stacklayout import StackLayout 
from kivy.uix.button import Button 
from kivy.uix.label import Label 
from kivy.clock import Clock 
from kivy.factory import Factory 

class MyWidget(BoxLayout): 
    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     button = Button(text="Print IDs", id="PrintIDsButton") 
     button.bind(on_release=self.print_label) 
     self.add_widget(button) 

     # crate some labels with defined IDs 
     for i in range(5): 
      self.add_widget(Button(text=str(i), id="button no: " + str(i))) 

     # update moved as per inclement's recommendation 
     Clock.schedule_interval(MyApp.update, 1/30.0) 

    def print_label(self, *args): 
     children = self.children[:] 
     while children: 
      child = children.pop() 
      print("{} -> {}".format(child, child.id)) 
      # we can change label properties from here! Woo! 
      children.extend(child.children) 
      if child.id == "PrintIDsButton": 
       child.text = child.text + " :)" 

class MyApp(App): 
    def build(self): 
     return MyWidget() 

    def update(self, *args): 
     #ERROR# AttributeError: 'float' object has no attribute 'root' 
     children = self.root.children[:] 

     #ERROR# TypeError: 'kivy.properties.ListProperty' object is not subscriptable 
     #children = MyWidget.children[:] 
     #while children: 
     # child = children.pop() 
     # print("{} -> {}".format(child, child.id)) 
     # children.extend(child.children) 

     #ERROR# TypeError: 'kivy.properties.ListProperty' object is not iterable 
     #for child in MyWidget.children: 
     # print("{} -> {}".format(child, child.id)) 
if __name__ == '__main__': 
    MyApp().run() 
  • 윈도우 7 SP1
  • Kivy 1.8.0/파이썬 3.3

나의 사과 : 여기

코드입니다!

답변

0

업데이트 기능을 'MyWidget'클래스에 넣은 다음 self.children을 호출하여 'MyWidget'내의 요소에 액세스했습니다.

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.stacklayout import StackLayout 
from kivy.uix.button import Button 
from kivy.uix.label import Label 
from kivy.clock import Clock 
from kivy.factory import Factory 

class MyWidget(BoxLayout): 
    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     button = Button(text="Print IDs", id="PrintIDsButton") 
     button.bind(on_release=self.print_label) 
     self.add_widget(button) 

     # crate some labels with defined IDs 
     for i in range(5): 
      self.add_widget(Button(text=str(i), id="button no: " + str(i))) 

     # update moved as per inclement's recommendation 
     Clock.schedule_interval(self.update, 1/5.0) 

    def print_label(self, *args): 
     children = self.children[:] 
     while children: 
      child = children.pop() 
      print("{} -> {}".format(child, child.id)) 
      # Add smiley by ID 
      children.extend(child.children) 
      if child.id == "PrintIDsButton": 
       child.text = child.text + " :)" 

    def update(self, *args): 
     children = self.children[:] 
     while children: 
      child = children.pop() 
      # remove smiley by ID 
      if child.id == "PrintIDsButton": 
       child.text = "Print IDs" 

class MyApp(App): 
    def build(self): 
     return MyWidget() 

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

다시 한번 감사드립니다!

2
children = MyWidget.children[:] 

MyWidget 클래스 자체가 아니라 그것의 인스턴스 (그리고 시간 내 주셔서 감사합니다), 그래서 아이들은 ListProperty 객체가 아니라 당신이 원하는 실제 목록입니다.

대신 루트 위젯 인 MyWidget 인스턴스의 하위 인 self.root.children을 원합니다.

또한 클래스 수준에서 업데이트 기능을 예약합니다. 나는 이것이 나쁜 습관이라고 생각하고 미묘한 벌레를 낳을 수있다. 위젯 대신 __init__ 메소드를 사용하는 것이 더 일반적입니다.

+0

감사합니다. 귀하의 권장 사항에 따라 시계 일정 업데이트 기능이 이동되었습니다. 위에서 설명한대로 오류가 계속 발생합니다. –

관련 문제