kivy

kivy戦記(17) 自分のメソッドを、別のclassで「OK」が押されたときに実行させる

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

いよいよメインのAllSCNへ。
前回、自分のソースは読みにくいということで、しびれを切らせてjsonの読み込みと書き込みを、class分けしました。

filelist.py


import os
import sys
import json
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeViewLabel
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
from pprint import pprint
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()
path_inf = 'path_inf.json'
class PathRead():
    def __init__(self, **kwargs):
        self.path_json = None
        self.notfound = False
        try:
            #raise PermissionError('やっちまったな')
            with open(path_inf, 'r') as fd:
                self.path_json = json.load(fd)
        except FileNotFoundError as err:
            self.notfound = True
        except PermissionError as err:
            self.msg = '保存データを読み込もうとしましたが、読み込み許可がありません。\n'
            self.msg += '読みこもうとしたパス・ファイルは、' + path_inf + 'です。\n'
            self.msg += '保存データの読み込み許可を確認するか、パス・ファイルが適当かを確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button= self.btn_ok, \
                 message_text= self.msg)
            self.popup = Popup(title='読み込み許可エラー', content=content)
            self.popup.open()
        except IOError as err:
            self.msg = '保存データを読み込もうとしましたが、読み込めません。\n'
            self.msg += '読み込み先機器に問題があるようです。\n'
            self.msg += '読み込み先機器の状態を確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button= self.btn_ok, \
                 message_text= self.msg)
            self.popup = Popup(title='I/Oエラー', content=content)
            self.popup.open()
        except BaseException as err:
            self.msg = '保存データを読み込もうとしましたが、何らかのエラーが起きました。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button= self.btn_ok, \
                 message_text= self.msg)
            self.popup = Popup(title='その他のエラー', content=content)
            self.popup.open()
    def btn_ok(self):
        self.popup.dismiss()
class PathWrite():
    def __init__(self, **kwargs):
        self.err = True
        path_inf_dict = kwargs['path_inf_dict']
        self.pd = {}
        self.pd['begin_path'] = path_inf_dict['begin_path']
        try:
            # raise OverflowError('やっちまったな')
            with open(path_inf, 'w') as fd:
                json.dump(self.pd, fd)
                self.err = False
        except PermissionError as err:
            self.msg = '保存データを書き込もうとしましたが、書き込み許可がありません。\n'
            self.msg += 'パスは、' + self.pd['begin_path'] + 'です。\n'
            self.msg += '保存先の書き込み許可を確認するか、パスが適当かを確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button=self.btn_ok, \
                 message_text=self.msg)
            self.popup = Popup(title='書き込み許可エラー', content=content)
            self.popup.open()
        except IOError as err:
            self.msg = '保存データを書き込もうとしましたが、書き込めません。\n'
            self.msg += '書き込み先機器に問題があるようです。\n'
            self.msg += '書き込み先機器の状態を確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button=self.btn_ok, \
                 message_text=self.msg)
            self.popup = Popup(title='I/Oエラー', content=content)
            self.popup.open()
        except BaseException as err:
            self.msg = '保存データを書き込もうとしましたが、何らかのエラーが起きました。\n\n'
            self.msg += str(err)
            content = MsgboxOk \
                (ok_button=self.btn_ok, \
                 message_text=self.msg)
            self.popup = Popup(title='その他のエラー', content=content)
            self.popup.open()
    def btn_ok(self):
        pprint ('OKが押されました')
        self.popup.dismiss()

class MsgboxOk(BoxLayout):
    message_text = StringProperty()
    ok_button = ObjectProperty(None)
class MsgboxOkCancel(BoxLayout):
    message_text = StringProperty()
    ok_button = ObjectProperty(None)
    cancel_button = ObjectProperty(None)
class SetSCN(Screen):
    begin_path_dsp = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
    def setBeginPathCheck(self):
        if os.path.isdir(self.begin_path_dsp.text) == False:
            return False
        return True
    def setSelect(self):
        begin_path_result = self.setBeginPathCheck()
        if begin_path_result == True:
            self._popup = LstPOP(load=self.setSelectLoad, \
                                 cancel=self.setSelectCancel, \
                                 start_path=self.begin_path_dsp.text)
            self._popup.open()
        else:
            self.msg = '入力した開始パスが存在しません\n\n'
            self.msg += self.begin_path_dsp.text
            content = MsgboxOk \
                (ok_button=self.msgTestOk, \
                 message_text=self.msg)
            self.popup = Popup(title='入力エラー', content=content)
            self.popup.open()
            self.begin_path_dsp.text = sm.begin_path_previous
    def setSelectLoad (self, path, filename):
        self.begin_path_dsp.text = path
        sm.begin_path_previous = path
        self._popup.dismiss()
    def setSelectCancel(self):
        self._popup.dismiss()
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
    def selfOk(self):
        begin_path_result = self.setBeginPathCheck()
        if begin_path_result == True:
            self.pd = {}
            self.pd['begin_path'] = self.begin_path_dsp.text
            pw = PathWrite(path_inf_dict=self.pd)
            if pw.err == False:
                self.manager.get_screen('all').file_name.text = self.begin_path_dsp.text
                sm.current = 'all'

        else:
            self.msg = '入力した開始パスが存在しません\n\n'
            self.msg += self.begin_path_dsp.text
            content = MsgboxOk \
                (ok_button=self.msgTestOk, \
                 message_text=self.msg)
            self.popup = Popup(title='入力エラー', content=content)
            self.popup.open()
            self.begin_path_dsp.text = sm.begin_path_previous
    def selfCancel(self):
        sm.current = 'all'
class LstPOP(Popup):
    #current_dir = os.path.dirname(os.path.abspath(__file__))
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)
    start_path = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(LstPOP, self).__init__(**kwargs)
        self.title ='読み込み中 ' + self.start_path
    def is_dir(self, dirname, filename):
        # ディスレクトリならTrueを返す
        return os.path.isdir(os.path.join(dirname, filename))
    def lstChooser(self, path, selection):
        if 0 < len(selection):
            self.title = '読み込み中 ' + selection[0]
class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
    def msgOsErrorOk(self):
        print('OKが押されました')
        self.popup.dismiss()
        sys.exit()
    def begin_display(self, dt):
        #
        # SetSCNの最初期内容
        #
        self.init_path = ''
        thisos = os.name
        if thisos == 'posix':
            self.init_path = os.environ.get('HOME')
        elif thisos == 'nt':
            self.init_path = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH')
        else:
            msg = '内部OS判定(os.name)が、"' + thisos + '”でした。\n'
            msg += 'サポートしているOSは、UNIX系統と、Windowsです。\n'
            msg += 'したがってこのOSはサポート外です。すみません。'
            content = MsgboxOk \
                (ok_button= self.msgOsErrorOk, \
                message_text= msg)
            self.popup = Popup(title='OSサポートエラー', content=content)
            self.popup.open()
            return
        #
        # AllSCN用の初期設定 ファイルパス読み込み
        #
        pr = PathRead()
        if pr.path_json != None:
            path_inf_begin = pr.path_json['begin_path']
            self.manager.get_screen('set').begin_path_dsp.text = path_inf_begin
            self.file_name.text = path_inf_begin
            sm.begin_path_previous = path_inf_begin
        else:
            if pr.notfound == True:
                self.manager.get_screen('set').begin_path_dsp.text = self.init_path
                self.file_name.text = self.init_path
                sm.begin_path_previous = self.init_path
            else:
                pass

        #
        # AllSCNのtree処理
        #
        self.tv.add_node(TreeViewLabel(text ='シンカリオン E1 とき'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン 0 ひかり'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン キハ32 鉄道ホビートレイン'))
    def setupButtonClicked(self):
        #
        # SetSCNへの画面遷移時の内容
        #
        sm.current = 'set'

    def show_load(self):
        # 暫定ロジックです
        self._popup = LstPOP(   load = self.load, \
                                cancel = self.dismiss_popup, \
                                start_path='あああ')
        self._popup.open()
    def load (self, path, filename):
        pprint(filename)
        #self.file_name.text = filename[0]
        self.file_name.text = path
        #with open (os.path.join(path, filename[0])) as stream:
        #    self.text_input.text = stream.read()
        self.dismiss_popup()
    def dismiss_popup(self):
        self._popup.dismiss()
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
class FilelistApp(App):
    def build(self):
        allscn = AllSCN()
        setscn = SetSCN()
        Clock.schedule_once(allscn.begin_display, 0)
        sm.add_widget(allscn)
        sm.add_widget(setscn)
        return sm
if __name__ == '__main__':
    FilelistApp().run()

filelist.kvは、変更なし(「kivy戦記(16-10) json読み込みから、一通り動くか確認してみる」https://koh-sen.jp/blog/archives/7496時点が最新)
なお、path_inf.jsonの中身は、「・・・/左巻きなると」である。
で、動かしてみる。

おお、jsonの内容がちゃんと反映されている。
しかし、エラーロジックの再確認をしている段階で問題が起きた。
PathRead()の中でPermissionErrorを意図的に発生させていたときのことであった。

このエラーメッセージはいいんだが、「OK」を押下すると、

こりゃまずいね。
強制終了しなきゃいけなかった。
しかし、この


class AllSCN(Screen):
(省略ですわ)
        #
        # AllSCN用の初期設定 ファイルパス読み込み
        #
        pr = PathRead()
        if pr.path_json != None:
            path_inf_begin = pr.path_json['begin_path']
            self.manager.get_screen('set').begin_path_dsp.text = path_inf_begin
            self.file_name.text = path_inf_begin
            sm.begin_path_previous = path_inf_begin
        else:
            if pr.notfound == True:
                self.manager.get_screen('set').begin_path_dsp.text = self.init_path
                self.file_name.text = self.init_path
                sm.begin_path_previous = self.init_path
            else:
                sys.exit() #PathRead()でエラーになった時の処理
        #
        # AllSCNのtree処理
        #
        self.tv.add_node(TreeViewLabel(text ='シンカリオン E1 とき'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン 0 ひかり'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン キハ32 鉄道ホビートレイン'))

PathRead()のエラー時処理の部分のpassがsys.exit()にした場合、エラーではないにもかかわらずいきなり終了するという現象が発生した。
どうやら、PathRead()を呼び出すと、内容如何に関わらず以後の処理を行ってしまうのだ。つまり、TreeViewLabelのシンカリオンの処理まで行ってしまうのだ。
ああ、そうか、だからOKボタンを押すイベントの処理があるんだ。
まさに「やっちまったな」の世界である。
では気を取り直して、PathRead()の「OK」ボタン押下時の処理に、そのままこの専用の処理を実行させる様にしよう。

filelist.py


import os
import sys
import json
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeViewLabel
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
from pprint import pprint
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()
path_inf = 'path_inf.json'
class PathRead:
    def __init__(self, **kwargs):
        self.path_json = None
        self.notfound = False
        self.err = False
        try:
            #raise BaseException('やっちまったな')
            with open(path_inf, 'r') as fd:
                self.path_json = json.load(fd)
        except FileNotFoundError:
            self.notfound = True
        except PermissionError as err:
            self.msg = '保存データを読み込もうとしましたが、読み込み許可がありません。\n'
            self.msg += '読みこもうとしたパス・ファイルは、' + path_inf + 'です。\n'
            self.msg += '保存データの読み込み許可を確認するか、パス・ファイルが適当かを確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='読み込み許可エラー', content=content)
            self.popup.open()
            self.err = True
        except IOError as err:
            self.msg = '保存データを読み込もうとしましたが、読み込めません。\n'
            self.msg += '読み込み先機器に問題があるようです。\n'
            self.msg += '読み込み先機器の状態を確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='I/Oエラー', content=content)
            self.popup.open()
            self.err = True
        except BaseException as err:
            self.msg = '保存データを読み込もうとしましたが、何らかのエラーが起きました。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='その他のエラー', content=content)
            self.popup.open()
            self.err = True
    def btn_ok(self):
        self.popup.dismiss()
class PathWrite:
    def __init__(self, **kwargs):
        self.err = True
        path_inf_dict = kwargs['path_inf_dict']
        self.pd = {}
        self.pd['begin_path'] = path_inf_dict['begin_path']
        try:
            #raise BaseException('やっちまったな')
            with open(path_inf, 'w') as fd:
                json.dump(self.pd, fd)
                self.err = False
        except PermissionError as err:
            self.msg = '保存データを書き込もうとしましたが、書き込み許可がありません。\n'
            self.msg += 'パスは、' + self.pd['begin_path'] + 'です。\n'
            self.msg += '保存先の書き込み許可を確認するか、パスが適当かを確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='書き込み許可エラー', content=content)
            self.popup.open()
        except IOError as err:
            self.msg = '保存データを書き込もうとしましたが、書き込めません。\n'
            self.msg += '書き込み先機器に問題があるようです。\n'
            self.msg += '書き込み先機器の状態を確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='I/Oエラー', content=content)
            self.popup.open()
        except BaseException as err:
            self.msg = '保存データを書き込もうとしましたが、何らかのエラーが起きました。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='その他のエラー', content=content)
            self.popup.open()
    def btn_ok(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
class MsgboxOk(BoxLayout):
    message_text = StringProperty()
    btn_ok = ObjectProperty(None)
class MsgboxOkWithPost(BoxLayout):
    message_text = StringProperty()
    btn_ok = ObjectProperty(None)
    btn_ok_post = ObjectProperty(None)
''' 幽霊class
class MsgboxOkCancel(BoxLayout):
    message_text = StringProperty()
    ok_button = ObjectProperty(None)
    cancel_button = ObjectProperty(None)
    '''

class SetSCN(Screen):
    begin_path_dsp = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
    def setBeginPathCheck(self):
        if os.path.isdir(self.begin_path_dsp.text) == False:
            return False
        return True
    def setSelect(self):
        begin_path_result = self.setBeginPathCheck()
        if begin_path_result == True:
            self._popup = LstPOP(load=self.setSelectLoad, \
                                 cancel=self.setSelectCancel, \
                                 start_path=self.begin_path_dsp.text)
            self._popup.open()
        else:
            self.msg = '入力した開始パスが存在しません\n\n'
            self.msg += self.begin_path_dsp.text
            content = MsgboxOk (\
                 btn_ok=self.msgTestOk, \
                 message_text=self.msg)
            self.popup = Popup(title='入力エラー', content=content)
            self.popup.open()
            self.begin_path_dsp.text = sm.begin_path_previous
    def setSelectLoad (self, path, filename):
        self.begin_path_dsp.text = path
        sm.begin_path_previous = path
        self._popup.dismiss()
    def setSelectCancel(self):
        self._popup.dismiss()
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
    def selfOk(self):
        begin_path_result = self.setBeginPathCheck()
        if begin_path_result == True:
            self.pd = {}
            self.pd['begin_path'] = self.begin_path_dsp.text
            pw = PathWrite( \
                path_inf_dict=self.pd, \
                btn_ok_post=self.pathwhite_ng)
            if pw.err == False:
                self.manager.get_screen('all').file_name.text = self.begin_path_dsp.text
                sm.current = 'all'
        else:
            self.msg = '入力した開始パスが存在しません\n\n'
            self.msg += self.begin_path_dsp.text
            content = MsgboxOk (\
                 btn_ok=self.msgTestOk, \
                 message_text=self.msg)
            self.popup = Popup(title='入力エラー', content=content)
            self.popup.open()
            self.begin_path_dsp.text = sm.begin_path_previous
    def selfCancel(self):
        sm.current = 'all'
    def pathwhite_ng(self):
        #
        # PathWhite()で異常だった時の処理
        #
        print('json書き込み 異常だで終了したがや')
        sys.exit()

class LstPOP(Popup):
    #current_dir = os.path.dirname(os.path.abspath(__file__))
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)
    start_path = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(LstPOP, self).__init__(**kwargs)
        self.title ='読み込み中 ' + self.start_path
    def is_dir(self, dirname, filename):
        # ディスレクトリならTrueを返す
        return os.path.isdir(os.path.join(dirname, filename))
    def lstChooser(self, path, selection):
        if 0 < len(selection):
            self.title = '読み込み中 ' + selection[0]
class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
    def msgOsErrorOk(self):
        print('OKが押されました')
        self.popup.dismiss()
        sys.exit()
    def begin_display(self, dt):
        #
        # SetSCNの最初期内容
        #
        self.init_path = ''
        thisos = os.name
        if thisos == 'posix':
            self.init_path = os.environ.get('HOME')
        elif thisos == 'nt':
            self.init_path = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH')
        else:
            msg = '内部OS判定(os.name)が、"' + thisos + '”でした。\n'
            msg += 'サポートしているOSは、UNIX系統と、Windowsです。\n'
            msg += 'したがってこのOSはサポート外です。すみません。'
            content = MsgboxOk (\
                btn_ok=self.msgOsErrorOk, \
                message_text=msg)
            self.popup = Popup(title='OSサポートエラー', content=content)
            self.popup.open()
            return
        #
        # AllSCN用の初期設定 ファイルパス読み込み
        #
        pr = PathRead(btn_ok_post=self.pathread_ng)
        print('PathRead通過しました')
        if pr.path_json != None:
            #
            # PathRead()で正常だった時の処理
            #
            print('json読み込み 正常だがや')
            path_inf_begin = pr.path_json['begin_path']
            self.manager.get_screen('set').begin_path_dsp.text = path_inf_begin
            self.file_name.text = path_inf_begin
            sm.begin_path_previous = path_inf_begin
        else:
            if pr.notfound == True:
                self.manager.get_screen('set').begin_path_dsp.text = self.init_path
                self.file_name.text = self.init_path
                sm.begin_path_previous = self.init_path
        if pr.err == False:
            # AllSCNのtree処理
            self.tv.add_node(TreeViewLabel(text='シンカリオン E1 とき'))
            self.tv.add_node(TreeViewLabel(text='シンカリオン 0 ひかり'))
            self.tv.add_node(TreeViewLabel(text='シンカリオン キハ32 鉄道ホビートレイン'))
    def pathread_ng(self):
        #
        # PathRead()で異常だった時の処理
        #
        print('json読み込み 異常だで終了したがや')
        sys.exit()

    def setupButtonClicked(self):
        #
        # SetSCNへの画面遷移時の内容
        #
        sm.current = 'set'
    def show_load(self):
        # 暫定ロジックです
        self._popup = LstPOP(   load = self.load, \
                                cancel = self.dismiss_popup, \
                                start_path='あああ')
        self._popup.open()
    def load (self, path, filename):
        pprint(filename)
        #self.file_name.text = filename[0]
        self.file_name.text = path
        #with open (os.path.join(path, filename[0])) as stream:
        #    self.text_input.text = stream.read()
        self.dismiss_popup()
    def dismiss_popup(self):
        self._popup.dismiss()
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
class FilelistApp(App):
    def build(self):
        allscn = AllSCN()
        setscn = SetSCN()
        Clock.schedule_once(allscn.begin_display, 0)
        sm.add_widget(allscn)
        sm.add_widget(setscn)
        return sm
if __name__ == '__main__':
    FilelistApp().run()

filelist.kv


<SetSCN>:
    name: 'set'
    begin_path_dsp: begin_path_dsp
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            size_hint_y: 0.1
            orientation: 'horizontal'
            BoxLayout:
                Label:
                    size_hint_x: 0.1
                    text: '開始パス'
                TextInput:
                    id: begin_path_dsp
                    size_hint_x: 0.8
                Button:
                    size_hint_x: 0.1
                    text: '…'
                    on_release: root.setSelect()
        BoxLayout:
            size_hint_y: 0.8
        BoxLayout:
            size_hint_y: 0.1
            Button:
                size_hint_x: 0.5
                text: 'OK'
                on_release: root.selfOk()
            Button:
                size_hint_x: 0.5
                text: 'キャンセル'
                on_release: root.selfCancel()
<AllSCN>:
    name: 'all'
    tv: tv
    file_name: file_name
    BoxLayout:
        orientation: 'vertical'
        BoxLayout: #OpnSCN
            size_hint_y: 0.1
            orientation: 'horizontal'
            BoxLayout:
                Button:
                    size_hint_x: 0.1
                    text: '設定'
                    on_release: root.setupButtonClicked()
                TextInput:
                    id: file_name
                    size_hint_x: 0.7
                    text: 'ファイルパス'
                Button:
                    size_hint_x: 0.1
                    text: '…'
                    on_release: root.show_load()
                Button:
                    size_hint_x: 0.1
                    text: '実行'
        BoxLayout: #ResultSCN
            size_hint_y: 0.9
            TreeView:
                id: tv
<MsgboxOk>
    orientation: 'vertical'
    Label:
        size_hint_y: 0.9
        text: root.message_text
    BoxLayout:
        size_hint_y: 0.1
        orientation: 'horizontal'
        Button:
            size_hint_x: 10
            text: '了解'
            on_release:
                root.btn_ok()
<MsgboxOkWithPost>
    orientation: 'vertical'
    Label:
        size_hint_y: 0.9
        text: root.message_text
    BoxLayout:
        size_hint_y: 0.1
        orientation: 'horizontal'
        Button:
            size_hint_x: 10
            text: 'OK'
            on_release:
                root.btn_ok()
                root.btn_ok_post()

<MsgboxOkCancel>
    orientation: 'vertical'
    Label:
        size_hint_y: 0.9
        text: root.message_text
    BoxLayout:
        size_hint_y: 0.1
        orientation: 'horizontal'
        Button:
            size_hint_x: 10
            text: 'OK'
            on_release: root.ok_button()
        Button:
            size_hint_x: 10
            text: 'キャンセル'
            on_release: root.cancel_button()
<LstPOP>:
    id:lst_pop
    size_hint: 0.9, 0.9
    #title: '読み込み中 ' + root.start_path
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: 'vertical'
        FileChooserListView:
            id: filechooser
            dirselect: True
            path: root.start_path
            filters: [root.is_dir]
            on_touch_down: lst_pop.lstChooser(filechooser.path, filechooser.selection)
        BoxLayout:
            size_hint_y : None
            height : 30
            Button:
                text: 'キャンセル'
                on_release: root.cancel()
            Button:
                text: '読み込み'
                on_release: root.load(filechooser.path, filechooser.selection)
AllSCN:

これで、いろいろ確認したところ、どうやら問題がなさそうだ。

まず、filelist.kv。

<MsgboxOkWithPost>
    orientation: 'vertical'
    Label:
        size_hint_y: 0.9
        text: root.message_text
    BoxLayout:
        size_hint_y: 0.1
        orientation: 'horizontal'
        Button:
            size_hint_x: 10
            text: 'OK'
            on_release:
                root.btn_ok()
                root.btn_ok_post()

新設の<MsgboxOkWithPost>は、<MsgboxOk>のコピー。
ただし、on_release:したときの処理は、root.btn_ok()のあとに、root.btn_ok_post()を実行させるようにしている。
そして、この<MsgboxOkWithPost>のPythonソースの方では、

filelist.py(抜粋だわ)


class MsgboxOkWithPost(BoxLayout):
    message_text = StringProperty()
    btn_ok = ObjectProperty(None)
    btn_ok_post = ObjectProperty(None)

そしてこの、MsgboxOkWithPostを呼ぶ側では、

filelist.py(抜粋なのよ)


class PathRead:
    def __init__(self, **kwargs):
        self.path_json = None
        self.notfound = False
        self.err = False
        try:
            #raise BaseException('やっちまったな')
(省略)
        except PermissionError as err:
            self.msg = '保存データを読み込もうとしましたが、読み込み許可がありません。\n'
            self.msg += '読みこもうとしたパス・ファイルは、' + path_inf + 'です。\n'
            self.msg += '保存データの読み込み許可を確認するか、パス・ファイルが適当かを確認してください。\n\n'
            self.msg += str(err)
            content = MsgboxOkWithPost ( \
                btn_ok=self.btn_ok, \
                btn_ok_post=kwargs['btn_ok_post'], \
                message_text=self.msg)
            self.popup = Popup(title='読み込み許可エラー', content=content)
            self.popup.open()
            self.err = True

としている。
さらに、このReadPathを呼ぶ側では、

filelist.py(抜粋ですわ)


class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
(省略だわ)
    def begin_display(self, dt):
(省略したかったの)
        #
        # AllSCN用の初期設定 ファイルパス読み込み
        #
        pr = PathRead(btn_ok_post=self.pathread_ng)
        print('PathRead通過しました')

と言う風に、btn_ok_postを通して、self.pathread_ngというメソッドを指定している。
そしてそのself.pathread_ngとは、

filelist.py(抜粋よ)


class AllSCN(Screen):
(省略したわ)
    def pathread_ng(self):
        #
        # PathRead()で異常だった時の処理
        #
        print('json読み込み 異常だで終了したがや')
        sys.exit()

となるのだ。
つまり、
AllSCNpathread_ngの処理を実行させるために、PathReadのパラメータにこの処理を入れ、これの中のMsgboxOkWithPostを通して、「OK」ボタンが押下された処理に、PathReadのそのものの処理のあとに、そのAllSCNpathread_ngの処理を実行させるようにしているのだ。

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