kivy

kivy戦記(9-2) 強敵ObjectProperty(None)との闘い

kivy
この記事は約7分で読めます。
(2018-10-4追記)
ここで、kvファイル上のOpeSCNとResultSCNは、AllSCNの子として作って失敗して、その後そういう作り方をやめていますが、あとでkivy戦記(19-3) class間の受け渡しでドツボにはまる 以降で成功していますので、こういう使い方をするときは、そちらの方を参照してください。

では、ObjectPropertyを使って、Pythonとkvファイルのアクセスをしてみよう。
filelist.py


from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.label import Label
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
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')
class ResultSCN(Widget):
    txt = ObjectProperty(None)

    def __init__(self, **kwargs):
         super(ResultSCN, self).__init__(**kwargs)
         self.txt.text = 'うふふふふふふふ'
class OpeSCN(Widget):
    pass
class AllSCN(Widget):
    pass
class FilelistApp(App):
    def build(self):
        return AllSCN()
if __name__ == '__main__':
    FilelistApp().run()

filelist.kv


<AllSCN>:
    BoxLayout:
        orientation: 'vertical'
        size: root.size
        canvas.before:
            Color:
                rgba: 0,0,.5,1 # 青色
            Rectangle:
                pos: self.pos
                size: self.size
        OpeSCN:
            size_hint_y: 0.1
        ResultSCN:
            size_hint_y: 0.9
<OpeSCN>:
    BoxLayout:
        size: root.size
        pos: root.pos
        BoxLayout:
            TextInput:
                size_hint_x: 0.8
                text: 'ファイルパス'
            Button:
                size_hint_x: 0.1
                text: '…'
            Button:
                size_hint_x: 0.1
                text: '実行'
<ResultSCN>:
    txt: txt
    BoxLayout:
        size: root.size
        pos: root.pos
        Label:
            id: txt
            text: 'れれれれれれ'
AllSCN:

これで、「うふふふふふふふ」が出れば成功なのだが、、、、、


 Traceback (most recent call last):
   File "filelist.py", line 41, in 
     FilelistApp().run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 801, in run
     self.load_kv(filename=self.kv_file)
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 598, 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 381, in load_string
     widget = Factory.get(parser.root.name)()
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 345, in __init__
     Builder.apply(self, ignored_consts=self._kwargs_applied_init)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 451, in apply
     self._apply_rule(widget, rule, rule, ignored_consts=ignored_consts)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 567, in _apply_rule
     self._apply_rule(child, crule, rootrule)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 564, in _apply_rule
     child = cls(__no_builder=True)
   File "filelist.py", line 27, in __init__
     self.txt.text = 'うふふふふふふふ'
 AttributeError: 'NoneType' object has no attribute 'text'

なんでだろう、なんでだろう。
そもそも、Noneってなんだと思って調べたら、
Noneって、他言語のNullのことではないか!
と言うのが判明。(なにげなく使っていたのにね。)
filelist.pyの「self.txt.text」に、なんの定義もされていない。
つまり、txt = ObjectProperty(None)になにも入っていないということっぽい。
pycharmで動かしてみると、self.txtがに全く値が入っていない。

ちなみに、filelist.pyの「self.txt.text = ‘うふふふふふふふ’」をコメントアウトすると、

れれれのれーとなり、基本的にkvファイルそのものは、まともに出力することがわかる。
ロジックが通っていない可能性がある。
そういうわけで、kvファイルが入っているときのロジックの順序を調べることにした。

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