kivy

kivy戦記(16-4) 簡易版OS毎確認で、文字コードの問題が起きるの巻

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

さて、現在仮ロジックになっているOS毎設定を、正式なロジックにする。

 

Windowsの時、UNIX系統の時は、それぞれの環境設定を読み込むわけだが、その前に、そのほかのOSの時の処理を、エラーメッセージを表示して、処理を終わらせよう。

 

filelist.py


import os
import sys
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 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()
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):
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
    def selfOk(self):
        content = MsgboxOkCancel \
            (ok_button= self.msgTestOk, \
            cancel_button= self.msgTestCancel, \
            message_text= 'とりあえずボタンを作りましたよ')
        self.popup = Popup(title='ボタンだがや', content=content)
        self.popup.open()
        sm.current = 'all'
    def selfCancel(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 msgOsErrorOk(self):
        print('OKが押されました')
        self.popup.dismiss()
        sys.exit()
    def begin_display(self, dt):
        thisos = os.name
        if thisos == 'posix':
            print ('UNIX系統が動いています')
        elif thisos == 'nt':
            print ('Windowsが動いています')
        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
        print('AllSCNのbegin_displayは、続行されます')
        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):
        allscn = AllSCN(name='all')
        setscn = SetSCN(name='set')
        Clock.schedule_once(allscn.begin_display, 0)
        sm.add_widget(allscn)
        sm.add_widget(setscn)
        return sm
if __name__ == '__main__':
    FilelistApp().run()

 

メッセージ出力は、既存のMsgBoxOK()クラスを流用した。

したがって、filelist.kvは変更なし。

 

実際、Windows、UNIX系統以外のOSに乗せるのは今の環境では困難なので、デバッガを操作することにする

(それ以前に、動かないんじゃないか、と言うツッコミが来そうだが…)

 

判断ロジックの直前にブレークポイントを置く。そして変数thisosを操作する。

(その後のロジックで、os.nameを直接読まないのは、そのためなのだ。)

 

デバッグで実行して、ブレークポイントで止まったら、’posix’と’nt’以外の文字を入れる。

 

これで実行。

 

これでエラーメッセージが表示された。

エラーメッセージについては、前々からその表示内容に不満があって、
なぜ」こうなるのかという表示がない、あるいは軽く見られているという傾向にあり、それが不満だった。
今回のメッセージ内容では、どちらかというとレアケースになるのだが、なぜこうなるかを表示させたつもりである。
そして、このメッセージの「OK」ボタンを押すとアプリが終了する。

 

 

これで、その他OS処理は終了。

引き続き、UNIX系統とWindowsの処理を追加する。

 

filelist.py


import os
import sys
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 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()
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):
    def __init__(self, **kwargs):
        super(SetSCN, self).__init__(**kwargs)
    def msgTestOk(self):
        pprint ('OKが押されました')
        self.popup.dismiss()
    def msgTestCancel(self):
        pprint ('CANCELが押されました')
        self.popup.dismiss()
    def selfOk(self):
        content = MsgboxOkCancel \
            (ok_button= self.msgTestOk, \
            cancel_button= self.msgTestCancel, \
            message_text= 'とりあえずボタンを作りましたよ')
        self.popup = Popup(title='ボタンだがや', content=content)
        self.popup.open()
        sm.current = 'all'
    def selfCancel(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 msgOsErrorOk(self):
        print('OKが押されました')
        self.popup.dismiss()
        sys.exit()
    def begin_display(self, dt):
        path = ''

        thisos = os.name
        if thisos == 'posix':
            path = os.environ.get('HOME')
        elif thisos == 'nt':
            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
        print('pathは、' + path + 'です。')
        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):
        allscn = AllSCN(name='all')
        setscn = SetSCN(name='set')
        Clock.schedule_once(allscn.begin_display, 0)
        sm.add_widget(allscn)
        sm.add_widget(setscn)
        return sm
if __name__ == '__main__':
    FilelistApp().run()

 

filelist.kvは変更なし。

これで実行。コンソールは、

と、今動いている環境がUbuntuなので、これで良し。


で、Windowsのテストをしよう。

実は今動いているのは、ホストマシンがWindows10で、先ほど出たUbuntuはVirturalBoxによる仮想マシンなのだ。

最終的には、正式な配布状態にしたいが、この確認は最後の方へ持って行きたい。

 

というわけで、ホストマシンで確認することにしました。

実は、以前入れたことがあるわけです。

環境的には、

・Python 3.6.3

・kivy 1.10.0

なんです。

 

で、ホストマシンで動かしてみると、

なんだこりゃ。

で、よく考えたらkvファイルはUTF-8ではなく、Shift-JISでセーブしなければならないという、謎仕様を思い出した。

で、Shift-JISに変更してもう一度。

 

見づらいけど、これで良し。

 

ここで気になるのは、Ubntsu環境でも、もしかしたらkvファイルをUTF-8のほかにShift-JISで動かせるかという疑問である。

早速やってみる。

Ubuntu上で、Shift-JISになっていることを確認して、、、

 

 

あぎゃぎゃ。

UNIX系とWindowsとでは、そのままのkvファイルは使えず、コード変換が必要なのか。

めんどくせー。

 

その後スタッフが美味しくいただきました。ソースを元にに戻しておきました。

 

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