kivy

kivy戦記(15-2) 荒ぶるScreenManager

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

処理的には、これで、これで良かったと思っていた。

filelist.py


import os
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
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 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()
class MsgboxOk(BoxLayout):
    message_text = StringProperty()
    ok_button = ObjectProperty(None)
class SetSCN(Screen):
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
        content = MsgboxOk(ok_button= self.xxxOk, message_text= 'とりあえずボタンを作りましたよ')
        self.popup = Popup(title='ボタンだがや', content=content)
        self.popup.open()
    def xxxOk(self):
        self.popup.dismiss()
    def okButtonClicked(self):
        sm.current = 'all'
    def cancelButtonClicked(self):
        sm.current = 'all'
class LoadDialog(FloatLayout):
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)
class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(AllSCN, self).__init__(**kwargs)
        self.tv.add_node(TreeViewLabel(text ='シンカリオン E1 とき'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン 0 ひかり'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン キハ32 鉄道ホビートレイン'))
    def setupButtonClicked(self):
        sm.current = 'set'
    def show_load(self):
        content = LoadDialog(load = self.load, cancel = self.dismiss_popup)
        self._popup = Popup( title="読み込み中", content=content, size_hint=(0.9,0.9))
        self._popup.open()
    def load (self, path, filename):
        pprint(filename)
        self.file_name.text = filename[0]
        #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()
class FilelistApp(App):
    def build(self):
        sm.add_widget(AllSCN(name='all'))
        sm.add_widget(SetSCN(name='set'))
        return sm
if __name__ == '__main__':
    FilelistApp().run()

filelist.kv


<SetSCN>:
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            size_hint_y: 0.9
            Label:
                text: 'おほほ'
        BoxLayout:
            size_hint_y: 0.1
            Button:
                size_hint_x: 0.5
                text: 'OK'
                on_release: root.okButtonClicked()
            Button:
                size_hint_x: 0.5
                text: 'キャンセル'
                on_release: root.cancelButtonClicked()
<AllSCN>:
    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: 'OK'
            on_release: root.ok_button()

<LoadDialog>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: 'vertical'
        FileChooserListView:
            id: filechooser
        BoxLayout:
            size_hint_y : None
            height : 30
            Button:
                text: 'キャンセル'
                on_release: root.cancel()
            Button:
                text: '読み込み'
                on_release: root.load(filechooser.path, filechooser.selection)
AllSCN:

これを実行すると、、、、

なぜ、SetSCNを実行しないと出てこないメッセージが出てくるの?

どうやら、

class SetSCN(Screen):
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
        content = MsgboxOk(ok_button= self.xxxOk, message_text= 'とりあえずボタンを作りましたよ')
        self.popup = Popup(title='ボタンだがや', content=content)
        self.popup.open()

ここが問題らしい。

pycharmでトレースをかけてみたら、確かにボタンを押さなくてもSctSCNの__init__は起動している。

では、どうすればいいのか。

 

やめよう。

 

もともと、ここに入れるロジックではないし。

と言うわけで今の解釈は、screenmanagerで画面を管理している場合、画面の初期表示は__init__に書いていいが、popupは__init__に書くと、必ず表示される。そんな解釈をした。

screenmanagerは、RelativeLayoutを使っていて、最初にAllSCNとSetSCNの初期表示をする。

その際にpopupも同時に動く。

そんなところで良いのかな。

 

では気を取り直して、ロジックを少し修正してみよう。

SetSCNの「OK」ボタンが押されたら、popupが表示される。こうしよう。その方が実践に近い。

 

filelist.py


import os
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
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 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()
class MsgboxOk(BoxLayout):
    message_text = StringProperty()
    ok_button = ObjectProperty(None)
class SetSCN(Screen):
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
    def xxxOk(self):
        self.popup.dismiss()
    def okButtonClicked(self):
        content = MsgboxOk(ok_button= self.xxxOk, message_text= 'とりあえずボタンを作りましたよ')
        self.popup = Popup(title='ボタンだがや', content=content)
        self.popup.open()
        sm.current = 'all'
    def cancelButtonClicked(self):
        sm.current = 'all'
class LoadDialog(FloatLayout):
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)
class AllSCN(Screen):
    tv = ObjectProperty(None)
    file_name = ObjectProperty(None)
    loadfile = ObjectProperty(None)
    text_input = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(AllSCN, self).__init__(**kwargs)
        self.tv.add_node(TreeViewLabel(text ='シンカリオン E1 とき'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン 0 ひかり'))
        self.tv.add_node(TreeViewLabel(text ='シンカリオン キハ32 鉄道ホビートレイン'))
    def setupButtonClicked(self):
        sm.current = 'set'
    def show_load(self):
        content = LoadDialog(load = self.load, cancel = self.dismiss_popup)
        self._popup = Popup( title="読み込み中", content=content, size_hint=(0.9,0.9))
        self._popup.open()
    def load (self, path, filename):
        pprint(filename)
        self.file_name.text = filename[0]
        #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()
class FilelistApp(App):
    def build(self):
        sm.add_widget(AllSCN(name='all'))
        sm.add_widget(SetSCN(name='set'))
        return sm
if __name__ == '__main__':
    FilelistApp().run()

 

filelist.kvは変更なし。

これで実行してみよう。

 

「設定」ボタン押下。

 

「OK」ボタン押下。

 

 

無事目的のものが出た。

最後に、「OK」ボタンを押して、

 

元に戻ることを確認。

あの解釈で良かったみたい。

 

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