kivy

kivy戦記(19-3) class間の受け渡しでドツボにはまる

kivy
この記事は約15分で読めます。

いよいよ、前項で作ったkv19c.pyの結果をfilelist.pyやfilelist.kvに統合しようとしたのだけど、うまく動かない。

 


 Traceback (most recent call last):
   File "/home/*******/MyApp/01_filelist/filelist.py", line 506, in 
     FilelistApp().run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 799, in run
     self.load_kv(filename=self.kv_file)
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 596, in load_kv
     root = Builder.load_file(rfilename)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 301, in load_file
     return self.load_string(data, **kwargs)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 399, in load_string
     widget = Factory.get(parser.root.name)()
   File "/usr/lib/python3/dist-packages/kivy/uix/relativelayout.py", line 265, in __init__
     super(RelativeLayout, self).__init__(**kw)
   File "/usr/lib/python3/dist-packages/kivy/uix/floatlayout.py", line 65, in __init__
     super(FloatLayout, self).__init__(**kwargs)
   File "/usr/lib/python3/dist-packages/kivy/uix/layout.py", line 76, in __init__
     super(Layout, self).__init__(**kwargs)
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 348, in __init__
     Builder.apply(self, ignored_consts=self._kwargs_applied_init)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 469, in apply
     self._apply_rule(widget, rule, rule, ignored_consts=ignored_consts)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 585, in _apply_rule
     self._apply_rule(child, crule, rootrule)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 585, in _apply_rule
     self._apply_rule(child, crule, rootrule)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 582, in _apply_rule
     child = cls(__no_builder=True)
   File "/home/*******/MyApp/01_filelist/filelist.py", line 300, in __init__
     self.start_path = kwargs['start_path']
 KeyError: 'start_path'
プロセスは終了コード 1 で完了しました

この問題の部分が、

filelist.py(抜粋)


class ResultParts(BoxLayout):
    start_path = StringProperty(None)
    tv_p = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(ResultParts, self).__init__(**kwargs)
        self.start_path = kwargs['start_path']
        self.tv_p.bind(minimum_height = self.tv_p.setter('height'))
        self.tree_height = self.idv_dir(self.start_path, None)
(省略ですわ)
class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
(省略ですわ)
            # AllSCNのtree処理
            self.add_widget(ResultParts( start_path = self.file_name.text, btn_ok_post = self.fileread_ng))

これが、どうしてもわからなかった。

だから、もっと簡略化したものを作った。

kv19d.py


from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
# 日本語フォント設定
resource_add_path('./fonts')
LabelBase.register(DEFAULT_FONT, 'ipaexg.ttf')
sm = ScreenManager()
Builder.load_string('''
<ResultParts>:
    Label:
        text: root.rcAdd
<TestSCN>:
    BoxLayout:
        Label:
            text: 'AAAAA'
        ResultParts:
''')
class ResultParts(BoxLayout):
    rc = StringProperty()
    rcAdd = ObjectProperty()
    def __init__(self, **kwargs):
        super(ResultParts, self).__init__(**kwargs)
        self.rc = kwargs['start_path']
        self.rcAdd = self.rc + 'CCCCC'
class TestSCN(Screen):
    def __init__(self, **kwargs):
        super(TestSCN, self).__init__(**kwargs)
        self.add_widget(ResultParts(start_path='BBBBBB'))
class TestApp(App):
    def build(self):
        sm.add_widget(TestSCN(name='test'))
        return sm
if __name__ == '__main__':
    TestApp().run()

こんな画面を出したかった。

 

これを実行すると、さっきの同じエラーがでる。

 

つまり、


class TestSCN(Screen):
    def __init__(self, **kwargs):
        super(TestSCN, self).__init__(**kwargs)
        self.add_widget(ResultParts(start_path='BBBBBB'))

で、ResultPartsを呼んでいるのに、このstart_pathがないという現象である。

で、見てみたら


class ResultParts(BoxLayout):
    rc = StringProperty()
    rcAdd = ObjectProperty()
    def __init__(self, **kwargs):
        super(ResultParts, self).__init__(**kwargs)
        self.rc = kwargs['start_path']

ResultPartskwargsの中身がない。さて困った。

 

実験的に、TestSCNResultPartsを呼んでいるところをコメントアウトする。

kv19d.py


from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
# 日本語フォント設定
resource_add_path('./fonts')
LabelBase.register(DEFAULT_FONT, 'ipaexg.ttf')
sm = ScreenManager()
Builder.load_string('''
<ResultParts>:
    Label:
        text: root.rcAdd
<TestSCN>:
    BoxLayout:
        Label:
            text: 'AAAAA'
        ResultParts:
''')
class ResultParts(BoxLayout):
    rc = StringProperty()
    rcAdd = ObjectProperty()
    def __init__(self, **kwargs):
        super(ResultParts, self).__init__(**kwargs)
        #self.rc = kwargs['start_path']
        self.rcAdd = self.rc + 'CCCCC'
class TestSCN(Screen):
    def __init__(self, **kwargs):
        super(TestSCN, self).__init__(**kwargs)
        #self.add_widget(ResultParts(start_path='BBBBBB'))
class TestApp(App):
    def build(self):
        sm.add_widget(TestSCN(name='test'))
        return sm
if __name__ == '__main__':
    TestApp().run()

実行すると、

おや、それなりに動く。

ということは、この部分はなくてもいいかな?

そうすると、start_pathの内容は、どう渡せばいいんだろう?

 

では、ScreenManager経由でデータを渡してみよう。


from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
# 日本語フォント設定
resource_add_path('./fonts')
LabelBase.register(DEFAULT_FONT, 'ipaexg.ttf')
sm = ScreenManager()
Builder.load_string('''
<ResultParts>:
    Label:
        text: root.rcAdd
<TestSCN>:
    BoxLayout:
        Label:
            text: 'AAAAA'
        ResultParts:
''')
class ResultParts(BoxLayout):
    rc = StringProperty()
    rcAdd = ObjectProperty()
    def __init__(self, **kwargs):
        super(ResultParts, self).__init__(**kwargs)
        #self.rc = kwargs['start_path']
        self.rcAdd = sm.start_path + 'CCCCC'
class TestSCN(Screen):
    def __init__(self, **kwargs):
        super(TestSCN, self).__init__(**kwargs)
        #self.add_widget(ResultParts(start_path='BBBBBB'))
        sm.start_path = 'BBBBBB'
class TestApp(App):
    def build(self):
        sm.add_widget(TestSCN(name='test'))
        return sm
if __name__ == '__main__':
    TestApp().run()

で、実行すると、、、、、


 Traceback (most recent call last):
   File "/home/*******/MyApp/01_filelist/kv19d.py", line 61, in 
     TestApp().run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
     root = self.build()
   File "/home/*******/MyApp/01_filelist/kv19d.py", line 55, in build
     sm.add_widget(TestSCN(name='test'))
   File "/home/*******/MyApp/01_filelist/kv19d.py", line 47, in __init__
     super(TestSCN, self).__init__(**kwargs)
   File "/usr/lib/python3/dist-packages/kivy/uix/relativelayout.py", line 265, in __init__
     super(RelativeLayout, self).__init__(**kw)
   File "/usr/lib/python3/dist-packages/kivy/uix/floatlayout.py", line 65, in __init__
     super(FloatLayout, self).__init__(**kwargs)
   File "/usr/lib/python3/dist-packages/kivy/uix/layout.py", line 76, in __init__
     super(Layout, self).__init__(**kwargs)
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 348, in __init__
     Builder.apply(self, ignored_consts=self._kwargs_applied_init)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 469, in apply
     self._apply_rule(widget, rule, rule, ignored_consts=ignored_consts)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 585, in _apply_rule
     self._apply_rule(child, crule, rootrule)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 582, in _apply_rule
     child = cls(__no_builder=True)
   File "/home/*******/MyApp/01_filelist/kv19d.py", line 41, in __init__
     self.rcAdd = sm.start_path + 'CCCCC'
 AttributeError: 'ScreenManager' object has no attribute 'start_path'
プロセスは終了コード 1 で完了しました

あちゃー、、、、

smの中身を見てみたが、start_pathが入っていない。

 

ここで、深い深いまっくら森に突入することになる。

(続く)

 

タイトルとURLをコピーしました