質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

4419閲覧

kivyで、親のインスタンスの値を、子に渡す方法

退会済みユーザー

退会済みユーザー

総合スコア0

Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/09/14 05:47

編集2018/09/15 03:14

再びすみません。
テスト用に、kivyで簡単な画面を作っています。
これは、各classごとに開発という手法をとっています。

Python3

1from kivy.app import App 2from kivy.lang import Builder 3 4from kivy.uix.boxlayout import BoxLayout 5from kivy.uix.screenmanager import ScreenManager, Screen 6from kivy.properties import ObjectProperty 7from kivy.clock import Clock 8 9from kivy.core.text import LabelBase, DEFAULT_FONT 10from kivy.resources import resource_add_path 11 12Builder.load_string(''' 13<ResultParts> 14 ls_p: ls_v 15 Label: 16 id: ls_v 17 18<AllSCN>: 19 name: 'all' 20 us_p: us_v 21 22 BoxLayout: 23 orientation: 'vertical' 24 25 BoxLayout: #OpnSCN 26 Label: 27 id: us_v 28 BoxLayout: #ResultSCN 29 size_hint_y: 0.9 30 ResultParts: 31''') 32 33sm = ScreenManager() 34 35class ResultParts(BoxLayout): 36 ls_p = ObjectProperty() 37 38 def __init__(self, **kwargs): 39 super(ResultParts, self).__init__(**kwargs) 40 41 42class AllSCN(Screen): 43 us_p = ObjectProperty() 44 45 def __init__(self, **kwargs): 46 super(AllSCN, self).__init__(**kwargs) 47 48 def begin_display(self, dt): 49 self.us_p.text = 'AAA' 50 ResultParts.ls_p.text = 'BBB' 51 52 53 54class TestApp(App): 55 def build(self): 56 allscn = AllSCN() 57 58 Clock.schedule_once(allscn.begin_display, 0) 59 60 sm.add_widget(allscn) 61 62 return sm 63 64 65if __name__ == '__main__': 66 TestApp().run() 67

さて、AllSCNからResultPartsを経由して、下側のラベルに値'BBB'を出そうとしていたのですが、こんなエラーメッセージが出てしまいました。

Traceback (most recent call last): File "/home/arakawa/MyApp/01_filelist/kv19f.py", line 66, in <module> TestApp().run() File "/usr/lib/python3/dist-packages/kivy/app.py", line 826, in run runTouchApp() File "/usr/lib/python3/dist-packages/kivy/base.py", line 502, in runTouchApp EventLoop.window.mainloop() File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 727, in mainloop self._mainloop() File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 460, in _mainloop EventLoop.idle() File "/usr/lib/python3/dist-packages/kivy/base.py", line 337, in idle Clock.tick() File "/usr/lib/python3/dist-packages/kivy/clock.py", line 581, in tick self._process_events() File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events (kivy/_clock.c:7839) File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events (kivy/_clock.c:7597) File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events (kivy/_clock.c:7519) File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick (kivy/_clock.c:3258) File "/home/arakawa/MyApp/01_filelist/kv19f.py", line 50, in begin_display ResultParts.ls_p.text = 'BBB' AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'text' プロセスは終了コード 1 で完了しました

すでにインスタンスはできているはずなので、AllSCNの子のResultPartsにはアクセスできる気がしていたのですが、それができません。

AllSCNの子にResultPartsを設けるという構造は、できるだけ堅持したいのですが、どなたか教えていただけませんでしょうか?

開発環境
Python 3.5.2 + kivy 1.10.1 + Ubuntu16.04


ありがとうございましした。

ただ、試してみたのですが、まだうまくいきません。
あれからいろいろ当方でも試してみたのですが、いまだに'BBB'を出すことができません。

Python3

1from kivy.app import App 2from kivy.lang import Builder 3 4from kivy.uix.boxlayout import BoxLayout 5from kivy.uix.screenmanager import ScreenManager, Screen 6from kivy.properties import ObjectProperty 7from kivy.clock import Clock 8 9from kivy.core.text import LabelBase, DEFAULT_FONT 10from kivy.resources import resource_add_path 11 12Builder.load_string(''' 13<ResultParts> 14 ls_p: ls_v 15 Label: 16 id: ls_v 17 text: 'XXX' 18 19<AllSCN>: 20 name: 'all' 21 us_p: us_v 22 23 BoxLayout: 24 orientation: 'vertical' 25 26 BoxLayout: #OpnSCN 27 Label: 28 id: us_v 29 BoxLayout: #ResultSCN 30 size_hint_y: 0.9 31 ResultParts: 32''') 33 34sm = ScreenManager() 35 36class ResultParts(BoxLayout): 37 ls_p = ObjectProperty() 38 39 def __init__(self, **kwargs): 40 super(ResultParts, self).__init__(**kwargs) 41 Clock.schedule_once(self._once_after_init) 42 43 def _once_after_init(self, dt): 44 self.ls_p.text = 'before' 45 pass 46 47 def display(self): 48 print('ResultParts display:',self.linked) 49 self.ls_p.text = 'koteichi' 50 pass 51 52 53class AllSCN(Screen): 54 us_p = ObjectProperty() 55 56 def __init__(self, **kwargs): 57 super(AllSCN, self).__init__(**kwargs) 58 59 def on_pre_enter(self): 60 self.us_p.text = 'AAA' 61 rp = ResultParts() 62 rp.ls_p.text = 'BBB' 63 rp.linked = 'QQQ' 64 rp.display() 65 66 67class TestApp(App): 68 def build(self): 69 #allscn = AllSCN() 70 71 #Clock.schedule_once(allscn.begin_display, 0) 72 73 sm.add_widget(AllSCN()) 74 75 return sm 76 77 78if __name__ == '__main__': 79 TestApp().run() 80

この場合だと、下段に'koteichi'が出そうなものですが、実際には'before'がでてしまいました。
どうしたらよいのでしょうか。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

KivyのPropertyはClass属性じゃないので ResultParts.ls_p.text = 'BBB' じゃなくて ResultPartsのインスタンス.ls_p.text = 'BBB' と書かないといけないです。

Screenには元々on_pre_enter on_enterがあるのでbegin_display()の代わりになりますよ。

追記

on_pre_enter()内でrp = ResultParts() としてますが、これは新しいインスタンスを作ってるので、Kv言語上で作るように指示したインスタンスとは別物になります。

<AllSCN>: name: 'all' us_p: us_v BoxLayout: orientation: 'vertical' BoxLayout: #OpnSCN Label: id: us_v BoxLayout: #ResultSCN size_hint_y: 0.9 ResultParts: # <= このインスタンスとは別物

その上このrpはWidgetTreeに繋がってすらいない(add_widget()されていない)ので当然表示されないです。やりたい事はKv言語上で書いたResultPartsに対する操作だと思うので、以下のようにしてidを割り当てて

<AllSCN>: 略 BoxLayout: #ResultSCN size_hint_y: 0.9 ResultParts: id: resultparts

操作してください。

python

1 def on_pre_enter(self): 2 self.us_p.text = 'AAA' 3 rp = self.ids.resultparts # Kv言語上で書いたResultPartsを取得 4 rp.ls_p.text = 'BBB' 5 rp.linked = 'QQQ' 6 rp.display()

この場合だと、下段に'koteichi'が出そうなものですが、実際には'before'がでてしまいました。

AllScnはScreenManagerに加えられる最初の子なのでon_pre_enter()sm.add_widget(AllSCN())の時点で呼び出されます。それに対して _once_after_init()はClockで予約しているのでその後に呼び出されます。なのでbeforeが表示されるのは不思議なことではないです。これに対する対応はいくつか思い浮かびますが、その前に_once_after_init()内でself.ls_p.text = 'before'とするのは絶対に必要な処理ですか?例えば

<ResultParts> ls_p: ls_v Label: id: ls_v text: 'XXX'

<ResultParts> ls_p: ls_v Label: id: ls_v text: 'before'

とできない理由が何かあるのですか?

投稿2018/09/14 09:46

編集2018/09/15 04:41
gottadiveintopy

総合スコア736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/15 02:26

ありがとうございました。 ただ、まだ不具合があるので、よろしければ回答をお願いいたします。
gottadiveintopy

2018/09/15 03:02

何をしてどんな不具合が起きたのですか?
退会済みユーザー

退会済みユーザー

2018/09/15 03:15 編集

失礼しました。 本文に追加いたしました。 更新がうまくいかなかったようです。
退会済みユーザー

退会済みユーザー

2018/09/15 05:11 編集

確認できました。ありがとうございます。 _once_after_init()内のself.ls_p.text = 'before'は、確認用なので特にいらない処理です。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問