2013-10-24 31 views
1

我已經遇到了以下問題:kivy崩潰成功,如果在Python中的KV文件中使用的部件,文件

的例子(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 

2之間的差異是:

$ 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

它看起來像問題是,__init__方法實際上並沒有完全分析和設置KV說明,雖然我不知道的細節 - 我想人們留下了一些東西,計劃在事件回覆。當你嘗試檢查self.list_view時,你會得到None,因爲這還沒有設置。

如果你使用時鐘,你可以安排執行你的post_init的東西,到目前爲止(在kv指令完全執行完畢之後),但在下一幀之前進行。這是對你的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

謝謝,這也適用於我們。 這是一個錯誤或功能;-)在基維? – user2915097

+0

我很確定這是故意的,如果你喜歡的話,它是一個'功能',但當我快速瀏覽時,我不明白它爲什麼會這樣。可能其中一位開發人員會知道更多。 – inclement

+0

+1給你們倆。我確定它是這樣的!他們怎麼沒有在文檔中陳述? http://kivy.org/docs/api-kivy.properties.html –