2017-01-04 6 views
0

私のKivyアプリケーションに複数のListViewインスタンスを持たせたい。私は別のプロパティ、特にコールバックを割り当てることになると固執します。次のコードは私の問題を示しています。ここKivy AppでListViewのインスタンスごとに異なるプロパティを設定するにはどうすればよいですか?

from kivy.app import App 
from kivy.uix.listview import ListItemButton 
from kivy.uix.screenmanager import ScreenManager, Screen 
from kivy.lang import Builder 

Builder.load_string(''' 
#: import ListAdapter kivy.adapters.listadapter.ListAdapter 
#: import ListItemButton kivy.uix.listview.ListItemButton 
<smRoot>: 
    Screen1: 
    Screen2: 
<ListItemButton>: 
    on_press: app.callback1(self) 
    height: dp(25) 
    size_hint: (1,.1) 
<Screen1>: 
    name:'screen1' 
    BoxLayout: 
     orientation: 'vertical' 
     Label: 
      text: 'Screen1' 
      size_hint_y: .1 
     ListView: 
      id:lstScreen1  
      adapter: 
       ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}], 
       args_converter=lambda row_index, rec: {'text': rec['text']}, 
       cls=ListItemButton, 
       selection_mode='single', 
       allow_empty_selection=False) 
     Button: 
      text: 'Switch Screen' 
      size_hint_y: .1 
      on_press: root.manager.current = 'screen2' 
<ListItemButton>: 
    on_press: app.callback2(self) 
    height: dp(25) 
    size_hint: (1,.1)    
<Screen2>: 
    name:'screen2' 
    BoxLayout: 
     orientation: 'vertical' 
     Label: 
      text: 'Screen2' 
      size_hint_y: .1 
     ListView: 
      id:lstScreen2  
      adapter: 
       ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}], 
       args_converter=lambda row_index, rec: {'text': rec['text']}, 
       cls=ListItemButton, 
       selection_mode='single', 
       allow_empty_selection=False) 
     Button: 
      text: 'Switch Screen' 
      size_hint_y: .1 
      on_press: root.manager.current = 'screen1' 
''') 

class smRoot(ScreenManager): 
    pass 

class Screen1(Screen): 
    MyButt = ListItemButton 
    pass 

class Screen2(Screen): 
    pass 

class myApp(App): 
    def build(self): 
     smroot = smRoot() 
     return smroot 

    def callback1(self, btn_instance): 
     index = btn_instance.index 
     print 'From Screen 1: ' + str(index) 

    def callback2(self, btn_instance): 
     index = btn_instance.index 
     print 'From Screen 2: ' + str(index) 

myApp().run() 

、私は画面1と2のリストビューインスタンスのそれぞれが別々のコールバックを持っていると思います。

From Screen 2: 0 
From Screen 1: 0 

理想的には、私はDynamic Classのようなものを実装するために期待していた:私はどちらかの画面をクリックしたときには、出力はそうのような、同じです。私はこのような何かしようとしたとき、しかし:

<[email protected]>: 
    #on_press: app.callback1(self) 
    height: dp(25) 
    size_hint: (1,.1) 
<Screen1>: 
    name:'screen1' 
    MyButt: 
     on_press: app.callback1(self) 
    BoxLayout: 
     orientation: 'vertical' 
     Label: 
      text: 'Screen1' 
      size_hint_y: .1 
     ListView: 
      id:lstScreen1  
      adapter: 
       ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}], 
       args_converter=lambda row_index, rec: {'text': rec['text']}, 
       cls=MyButt, 
       selection_mode='single', 
       allow_empty_selection=False) 

を私はNameError: name 'MyButt' is not definedエラーを取得します。私が知る限りでは、上にリンクされたドキュメントの例と同じ構文を守っているので、私は混乱しています。

私はPythonでカスタムクラスを作成しようとしませんでしたが、私はむしろUI要素を.kvコードで分けておきます(私が間違っていないなら、kvの背後にある基本的なアイデアではないですか?

この点に関する助言/指針/提案は非常に高く評価されます。

あなたが(後に「:」)のpython側からウィジェットクラスを使用することはできません

答えて

0

それをインポートせずにKVに、しかしMyButt以来のことができます(純粋KVで定義された)動的クラスであること、任意のモジュールで定義されていません使用するにはFactoryを使用してください。

最初に、kvファイルの先頭にあるインポートファクトリ。

#:import Factory kivy.factory.Factory 

その後、

ListView: 
     id:lstScreen1  
     adapter: 
      ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}], 
      args_converter=lambda row_index, rec: {'text': rec['text']}, 
      cls=Factory.MyButt, 
+0

ListView: id:lstScreen1 adapter: ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}], args_converter=lambda row_index, rec: {'text': rec['text']}, cls=MyButt, 

を変更するには、ありがとう!迅速なフォローアップの質問:これは、paranthesisのすべてのもの、つまり 'ListAdapter(data = ...)'がPythonではなくkvを使って宣言されていた場合、この状況が回避されたことを意味しますか?一般的には、それが推奨される練習ですか? – ScissorHill

+0

kvで同じことができたら、Factoryを使うのを避けることができます。importなど、kivyはこれを許可しません。プロパティに割り当てる必要があるので、あなたのコードは右辺( ":"の右側)はPythonによって直接評価されるため、その特定の問題に対するより良い解決策はありません。要するに、KVlangはウィジェットを宣言するのに最適で、ListAdapterのような他のクラスを作成するのには適していません。 – Tshirtman

関連する問題