2013-10-24 3 views
1

나는 다음과 같은 문제가 발생한 파일 :kivy 충돌하는 경우

예 (mainok.py, testok.kv) 성공적으로 시작을

$ cat mainok.py 
from kivy.app import App 
from kivy.properties import ObjectProperty 
from kivy.uix.boxlayout import BoxLayout 
class BuddyList(BoxLayout): 
    list_view = ObjectProperty() 
    def __init__(self, **kwargs): 
     super(BuddyList, self).__init__(**kwargs) 
     assert(self.list_view is not None) 
     self.list_view.adapter.data = ['v1', 'v2'] 
    def roster_converter(self, index, txt): 
     result = { 
      "text": "%s %d" % (txt, index), 
      'size_hint_y': None, 
      'height': 25 
     } 
     return result 
class TestForm(BoxLayout): 
    text_input = ObjectProperty() 

    def __init__(self, **kwargs): 
     super(TestForm, self).__init__(**kwargs) 
     self.buddy_list = BuddyList() 
     self.add_widget(self.buddy_list) 
class TestokApp(App): 
    pass 
if __name__ == '__main__': 
    TestokApp().run() 

$ cat testok.kv 
#:import la kivy.adapters.listadapter 
#:import ku kivy.uix.listview 
TestForm: 
<BuddyList>: 
    list_view: list_view 
    ListView: 
     id: list_view 
     adapter: 
      la.ListAdapter(data=[], cls=ku.ListItemButton, 
      args_converter=root.roster_converter) 
<TestForm>: 
    orientation: 'vertical' 
    BoxLayout: 
     Label: 
      text: 'the label' 

이 예는 (mainko.py는 testko.kv)의 충돌 :

$ cat mainko.py 
from kivy.app import App 
from kivy.properties import ObjectProperty 
from kivy.uix.boxlayout import BoxLayout 
class BuddyList(BoxLayout): 
    list_view = ObjectProperty() 
    def __init__(self, **kwargs): 
     super(BuddyList, self).__init__(**kwargs) 
     assert(self.list_view is not None) 
     self.list_view.adapter.data = ['v1', 'v2'] 
    def roster_converter(self, index, txt): 
     result = { 
      "text": "%s %d" % (txt, index), 
      'size_hint_y': None, 
      'height': 25 
     } 
     return result 
class TestForm(BoxLayout): 
    text_input = ObjectProperty() 
    def __init__(self, **kwargs): 
     super(TestForm, self).__init__(**kwargs) 
class TestkoApp(App): 
    pass 
if __name__ == '__main__': 
    TestkoApp().run() 

$ cat testko.kv 
#:import la kivy.adapters.listadapter 
#:import ku kivy.uix.listview 
TestForm: 
<BuddyList>: 
    list_view: list_view 
    ListView: 
     id: list_view 
     adapter: 
      la.ListAdapter(data=[], cls=ku.ListItemButton, 
      args_converter=root.roster_converter) 
<TestForm>: 
    orientation: 'vertical' 
    BoxLayout: 
     Label: 
      text: 'the label' 
    BuddyList: 

충돌을 다음과 같은 오류

assert(self.list_view is not None) 
    AssertionError 
0 첫 번째는 성공 이유

$ diff -u mainko.py ../ok/mainok.py 
--- mainko.py  2013-10-23 14:11:26.976723764 +0200 
+++ ../ok/mainok.py 2013-10-23 14:12:34.976841090 +0200 
@@ -26,10 +26,13 @@ 

def __init__(self, **kwargs): 
    super(TestForm, self).__init__(**kwargs) 
+  self.buddy_list = BuddyList() 
+  self.add_widget(self.buddy_list) 

-class TestkoApp(App): 
+ 
+class TestokApp(App): 
    pass 

if __name__ == '__main__': 
- TestkoApp().run() 
+ TestokApp().run() 

$ diff -u testko.kv ../ok/testok.kv 
--- testko.kv  2013-10-23 14:10:11.948299722 +0200 
+++ ../ok/testok.kv 2013-10-23 14:16:51.352688453 +0200 
@@ -16,5 +16,4 @@ 
BoxLayout: 
    Label: 
     text: 'the label' 
- BuddyList: 

어떤 생각 두 번째는 실패 2 사이

의 차이점은 무엇입니까?

감사합니다,

답변

2

문제가 나는 세부 확실하지 않다 불구하고 __init__ 방법은 실제로 완전히의 KV 지침을 분석하고 설정하지 않는다는 것입니다 것 같습니다 - 나는 그것이 예정 몇 가지 물건을 잎 추측 이벤트 루프. self.list_view를 확인하려고하면 아직 설정되지 않았기 때문에 없음을 얻습니다.

시계를 사용하는 경우 지금까지 예약 된 모든 작업 (이후 kv 명령이 완전히 수행 된 후)이 아니라 다음 프레임 전에 post_init 작업을 수행 할 수 있습니다. 그런 일을하는 mainko.py에 대한 수정이 있습니다. 그것은 나를 위해 일하는 것 같다.

from kivy.app import App 
from kivy.properties import ObjectProperty 
from kivy.uix.boxlayout import BoxLayout 
from kivy.clock import Clock 

class BuddyList(BoxLayout): 
    list_view = ObjectProperty() 

    def __init__(self, **kwargs): 
     super(BuddyList, self).__init__(**kwargs) 
     Clock.schedule_once(self.post_init, 0) 

    def post_init(self, *args): 
     assert self.list_view is not None 
     self.list_view.adapter.data = ['v1', 'v2'] 

    def roster_converter(self, index, txt): 
     result = { 
      "text": "%s %d" % (txt, index), 
      'size_hint_y': None, 
      'height': 25 
     } 
     return result 

class TestForm(BoxLayout): 
    text_input = ObjectProperty() 
    def __init__(self, **kwargs): 
     super(TestForm, self).__init__(**kwargs) 


class TestkoApp(App): 
    pass 


if __name__ == '__main__': 
    TestkoApp().run() 
+0

감사합니다. 이것은 우리에게도 적용됩니다. kivy의 버그 또는 기능입니까? – user2915097

+0

나는 그것이 고의적이라고 확신한다. 당신이 원한다면 '기능'이지만, 내가 빨리 보았을 때 왜 그렇게 행동 하는지를 알 수 없었다. 아마 devs 중 하나가 더 많이 알 것입니다. – inclement

+0

+1. 나는 그것이 그렇게하는 것이 틀림 없음을 확신했다! 어떻게 그들이 문서에 그렇게 진술하지 않았습니까? http://kivy.org/docs/api-kivy.properties.html –