2016-08-23 73 views
0

私は現在、Kivyでカスタムウィジェットを含むPopupオブジェクトを含む単純なアプリケーションを作成しています。私は、メイン画面からウィジェット(ボタンの押下など)の情報にアクセスできるようにしたいが、ボタンがインスタンス化されていないという問題がある。Kivy - ポップアップでボタンをバインドする

(ほとんど)最小(部分的に)実施例を以下に示す。

import kivy 
kivy.require('1.9.1') 

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.popup import Popup 
from kivy.uix.checkbox import CheckBox 
from kivy.uix.button import Button 
from kivy.properties import ObjectProperty 
from kivy.lang import Builder 

Builder.load_string(''' 
<Main> 
    popup: popup 
    BoxLayout: 
     id: boxlayout 
     Button: 
      text: "Open Popup" 
      on_release: popup.open(); root.create_popup() 
     Popup: 
      id: popup 
      title: "Example popup" 
      on_parent: if self.parent == boxlayout: boxlayout.remove_widget(self) 
      PopupContent: 

<PopupContent>: 
    closer: closer 
    # Suppose there is a more complicated nested layout structure here 
    BoxLayout: 
     orientation: 'vertical' 
     CheckBox: 
     Button: 
      id: closer 
      text: "Close popup" 
''') 


class PopupContent(BoxLayout): 

    def __init__(self,**kwargs): 
     super(PopupContent, self).__init__(**kwargs) 


class Main(BoxLayout): 

    popup = ObjectProperty() 

    def __init__(self,**kwargs): 
     super(Main, self).__init__(**kwargs) 

    # Callback from button in PopupContent 
    def closer_callback(self,*args): 
     print("callback called!") 
     self.popup.dismiss() 

    # Creates container widget for popup and binds button to perform callback 
    def create_popup(self,*args): 
     popup_content = PopupContent() 
     popup_content.closer.bind(on_release = self.closer_callback) 

     # Problem: This returns "<type 'kivy.weakproxy.WeakProxy'>" 
     print(type(popup_content.closer)) 


class TestApp(App): 

    def build(self): 
     return Main() 

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

私は自分のコードに注釈を付けたように、私は押されたときに、私のメイン画面でメソッドを実行するためにPopupContentウィジェットにボタンをバインドしようとしましたが、ボタンがまだ作成されていないので、そのような結合が行われていません。

代わりにこのボタンをバインドすることはできますか?

答えて

0

私の例を作成するときに私は間違いを犯しました。私はPopupContentウィジェットのインスタンスを作成しましたが、私はをポップアップウィジェットに一度も追加しませんでした。それを修正すると、今は正常に動作します。

import kivy 
kivy.require('1.9.1') 

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.popup import Popup 
from kivy.uix.checkbox import CheckBox 
from kivy.uix.button import Button 
from kivy.properties import ObjectProperty 
from kivy.lang import Builder 

Builder.load_string(''' 
<Main> 
    popup: popup 
    BoxLayout: 
     id: boxlayout 
     Button: 
      text: "Open Popup" 
      on_release: popup.open(); root.create_popup() 
     Popup: 
      id: popup 
      title: "Example popup" 
      on_parent: if self.parent == boxlayout: boxlayout.remove_widget(self) 

<PopupContent>: 
    closer: closer 
    # Suppose there is a more complicated nested layout structure here 
    BoxLayout: 
     orientation: 'vertical' 
     CheckBox: 
     Button: 
      id: closer 
      text: "Close popup" 
''') 


class PopupContent(BoxLayout): 

    def __init__(self,**kwargs): 
     super(PopupContent, self).__init__(**kwargs) 


class Main(BoxLayout): 

    popup = ObjectProperty() 

    def __init__(self,**kwargs): 
     super(Main, self).__init__(**kwargs) 

    # Callback from button in PopupContent 
    def closer_callback(self,*args): 
     print("callback called!") 
     self.popup.dismiss() 

    # Creates container widget for popup and binds button to perform callback 
    def create_popup(self,*args): 
     popup_content = PopupContent() 
     self.popup.content = popup_content 
     popup_content.closer.bind(on_release = self.closer_callback) 

     # Note: This still returns "<type 'kivy.weakproxy.WeakProxy'>" 
     #  But the button is correctly bound regardless 
     print(type(popup_content.closer)) 


class TestApp(App): 

    def build(self): 
     return Main() 

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

私の理解では、PopupContentのインスタンスが最初に作成されたときにそれが表示された(おそらくいくつかのロード機能を経由して)されるまでは、パフォーマンス上の理由から、実際のウィジェットがロードされていないことです。それまではWeakProxy経由で "弱い参照"を取得しています。これによりバインディングが可能になります。

関連する問題