2017-06-28 20 views
0

私はずっとUbuntu 14.04でkivy 1.7.2を使っています。非常に使いやすいとkv言語は、デザインを簡単にします.... kvで実行することなく、DropDownはほとんど不可能であることが証明されていますが、さらに多くのPythonコードで起動すると問題を抱えている点を除いてDropDownは証明されています。ここで'NoneType'オブジェクトの単純なKivy DropDownエラーには 'bind'属性がありません

...私は

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.button import Button 
from kivy.uix.dropdown import DropDown 


kv_text = """#:kivy 1.7.2 
<MyWidget> 
    DropDown: 
     id: menupanel 
     on_parent: self.dismiss() 
     on_select: lambda: None 
     Button: 
      id: button_a 
      size_hint_y: None 
      text: "A" 
     Button: 
      id: button_b 
      size_hint_y: None 
      text: "B" 
    Button: 
     id: button_opendd 
     pos_hint: {"top":1, "right":1} 
     on_release: root.ids.menupanel.open(self) 
     text: "open" 
""" 

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

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

def main(): 
    Builder.load_string(kv_text) 
    app = MyWidgetApp() 
    app.run() 

if __name__ == '__main__': 
    main() 

....で始まるものです ....このエラーを生成する.... ...

Traceback (most recent call last): 
    File "wtfkivy.py", line 60, in <module> 
    main() 
    File "wtfkivy.py", line 57, in main 
    app.run() 
    File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 577, in run 
    root = self.build() 
    File "wtfkivy.py", line 52, in build 
    return MyWidget() 
    File "wtfkivy.py", line 48, in __init__ 
    super(FloatLayout, self).__init__(**kwargs) 
    File "/usr/lib/python2.7/dist-packages/kivy/uix/layout.py", line 61, in __init__ 
    super(Layout, self).__init__(**kwargs) 
    File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 163, in __init__ 
    Builder.apply(self) 
    File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1429, in apply 
    self._apply_rule(widget, rule, rule) 
    File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1531, in _apply_rule 
    child = cls(__no_builder=True) 
    File "/usr/lib/python2.7/dist-packages/kivy/uix/dropdown.py", line 160, in __init__ 
    self.container.bind(minimum_size=self._container_minimum_size) 
AttributeError: 'NoneType' object has no attribute 'bind' 

ドロップダウンさんself.containerGridLayoutにデフォルト設定されていますが、kvファイルで設定した場合は何とかなりません。

kvのDropDown:MyDropDown:に変更し、<MyDropDown>:の定義をすべて下に置くことで、このエラーを回避しました。その後、Pythonで、私はsuper(MyDropDown,self).__init__()でクラスを追加しなければならなかった!それは、ドロップダウンにウィジェットの重複セットを入れるだけです。うわー? (私は__init__(**kwargs)にINIT、私は同じバインドエラーで終わることに変更した場合。えっ?)

は、私は正直ほとんどkv経由で設定DropDownの良い例については、インターネット何度もこすり洗い、何も実際にヒットしないようしていますマーク。

たとえPythonで実装したとしても(super()、それは好まれません。メインアプリウィジェットの属性にアクセスできるようにするには、DropDownのウィジェットが必要です。

質問:ドロップダウンをほとんど完全にkv(これはデザインがきれいでアクセスしやすい)にする方法か、それともメインのアプリウィジェットにアクセスできるようにする方法ですか?

EDIT FJSevillaによって示さ及び試験によって確認されるように、ドロップダウンは、バージョン1.7.2に分割されます。多くの人がディストリビューションから提供されたバージョンを使用しているかもしれないので、私は精巧な答えを加えました。

答えて

0

DropDown(そしておそらく他のウィジェット)はKivy 1.7に分割されます。 DropDownは、特にkvコードから正しく開始されません。誰もがこの古いバージョンを使用する必要がある場合は、一人ではなくKVのpythonを使用してドロップダウンを実装する(トラブルを期待する)

dd = DropDown() 
b1 = Button(text="a") 
b2 = Button(text="b") 
dd.add_widget(b1) 
dd.add_widget(b2) 

それとも、少なくとも1.9.xにをアップグレード指名手配kivyを取得してみてください。 (私は1.8をテストしませんでした) 古いディストリビューションを使用している場合は、おそらくディストリビューションが提供するものを超えてkivyをアップグレードする必要があります。 Ubuntuの14.04で

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A863D2D6 
sudo add-apt-repository ppa:kivy-team/kivy-daily 
sudo apt-get update 
sudo apt-get install python-kivy python3-kivy 

このアップグレードは、特定の動作を変更するように見えることに注意してください(読み:新しいエラー)...

まず変更...ドロップダウンのために

on_parent:self.dismiss()ドロップダウン自体のバウンド属性でした。アップグレード後、DropDownはすぐに開かれたときに自動的に解除されました。 (あなたはそれが唯一の一瞬のためにちらつく参照。)

あなたは今、このエラーが発生した場合は、その問題を軽減するルートウィジェットに(menupanelの代わりにあなたのidを代入)menupanel.dismiss()を動かします。ルートウィジェット上menupanel.dismiss() OR self.ids.menupanel.dismiss()を持つ

第二に変更...どういうわけか

は、ドロップダウンへのREFを壊す(基本的に取得/強いREFを削除するガベージコレクション)し、この原因:

 on_release: menupanel.open(self) 
File "weakproxy.pyx", line 30, in kivy.weakproxy.WeakProxy.__getattr__ (kivy/weakproxy.c:1145) 
File "weakproxy.pyx", line 26, in kivy.weakproxy.WeakProxy.__ref__ (kivy/weakproxy.c:1069) 
ReferenceError: weakly-referenced object no longer exists 

(注:?私はinterwebsにこのエラーが表示さだけ時間がkvコードによってインスタンス化されている名前のクラス(すなわちclass MyButton(Button)のためにこれは普通の一般的なドロップダウンで、なぜここで問題が発生している)

エラーが発生した場合は、DropDownインスタンスへの参照を任意のオブジェクトに、インスタンス化するとき、またはドロップダウンが開いている関数に追加することです。他の参照が削除される前に起こるだけです。 (新しいScreenとバックに切り替えながら私の場合は、削除さばかり。)

class ... 
    def ... 
     self.backup_reference = self.ids.menupanel 

なぜ?何も思いつきません。

....または、ドロップダウンが非常に簡単になる場合は、1Spinnerを代わりに使用してみてください。

1

Kivy言語でのDropDownの使用はあまり直感的ではありません。しかし、それだけでKV-言語を使用して、独自のドロップダウンメニューを作成することが可能である:

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.floatlayout import FloatLayout 

kv_text = """\ 
#:kivy 1.7.2 
<MyWidget> 
    Widget: 
     on_parent: menupanel.dismiss() 

    DropDown: 
     id: menupanel 
     on_select: button_opendd.text = '{}'.format(args[1]) 

     Button: 
      text: 'A' 
      size_hint_y: None 
      height: 30 
      on_release: menupanel.select('A') 

     Button: 
      text: 'B' 
      size_hint_y: None 
      height: 30 
      on_release: menupanel.select('B') 

    Button: 
     id: button_opendd 
     pos_hint: {"top":1, "right":1} 
     text: 'Press' 
     on_release: menupanel.open(self) 
     size_hint_y: None 
     height: 40 
""" 

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

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

def main(): 
    Builder.load_string(kv_text) 
    app = MyWidgetApp() 
    app.run() 

if __name__ == '__main__': 
    main() 

警告:このコードはKivy 1.9.3とKivy 1.10.0でテストされ、私は知りませんそれがバージョン1.7と下位互換性がある場合。

あなたはKivy 1.10で正しくKivy 1.9にon_parentイベントインスタンスDropDown内のコードの実行を入れたが失敗した場合(メニューは常に隠されています)。例実行

enter image description here

+0

1.7.2では、そのコードには正確に同じエラーがあります。私はこれがUbuntu 14.04で配布されているバージョンのエラーであると想定していますか? – MookiBar

+0

@MookiBar、確か1.7バージョンとの互換性の問題です。 Kivy 1.7はすでにかなり古くなっています(2013年)、Kivy 1.10または1.9にアップグレードしない理由はありますか? – FJSevilla

+1

ですので、問題は完全にバージョンに関連しています。残念ながら、すべてのチェンジログをトロールするのに手間がかからず、「バージョンx.xより前に機能yが壊れている」という場所を見つけることができませんでした。IMHOでは、壊れたDropDownを出しました。それでも、私の目的のために働いたのではなく、それが良い一般的な参考資料であり、そしてその甘いグラフィックなので、あなたの答えをアップアップしました。 (申し訳ありませんが、SOスタッフ、それが不適切な場合) – MookiBar

関連する問題