まえがき
Save ボタンを作る
起動時に Load する
SomeDirectory を初期設定ファイルにする
まとめ
リストボックスの項目を増やしたり、そこから選んでテキストボックスに表示できるようになりましたが、項目を保存できると便利です(と言っても、このアプリケーション自体が便利なわけではないのですが)。そこで、「Save」ボタンを作ってリストボックスの内容を保存できるようにします。
ウィンドウに Save ボタンを加えて、それを押すとリストボックスの項目をファイルに保存するようにします。
前回までのspeak10.sit.bin(約 30k)に書き加えていきます。
speakwin.py 変更前:23 ---------------------------------------------- self.deletebutton = W.Button((160, 95, 60, 22), title = 'Delete', callback = self.delList) ---------------------------------------------- 変更後:23- ---------------------------------------------- self.deletebutton = W.Button((160, 95, 60, 22), title = 'Delete', callback = self.delList) self.savebutton = W.Button((20, -32, 60, 22), title = 'Save', callback = self.save) #追記 ----------------------------------------------
self.savebutton = W.Button((20, -32, 60, 22), title = 'Save', callback = self.save)
Speak ボタンの左に Save ボタンを加えました。「Save」というラベルがついて、押すと self.save メソッドが実行される、としました。だんだんボタンが多くなってきました。
speakwin.py 変更後:def delList(self) の後に追記 ---------------------------------------------- def save(self): fp = open(self.parent.preffilepath, 'w') import pickle pickle.dump(self.text, fp) fp.close() ----------------------------------------------
fp = open(self.parent.preffilepath, 'w')
ファイルを開きます。かなり前の回に書きましたが、self.parent にはアプリケーションのオブジェクト自身の参照が代入されています。その preffilepath は(MyApp.py の74行目)
preffilepath = ":SomeDirectory"
となっています。それを利用して、MyApp.py と同じディレクトリに「SomeDirectory」というファイルを作り、開きます。
import pickle
pickle.dump(self.text, fp)
fp.close()
書き込もうとしているのは、self.text というリストです。fp.write や fp.writelines を使って、1項目を1行にテキスト形式で書き込んでいく方法もいいのですが、リストボックスの1つの項目は1行とは限りません。起動時の
hello, "MyApp.py" template and W widgets world!
Excellent scroll bar.
Goodby!
のように改行を含んだ項目もあります。それで、リスト self.text をそのまま保存するために、pickle モジュールを使うことにしました。
以上のように speakwin.py を訂正して、MyApp.py を実行すると以下のようになります。
Save ボタンを押して、MyApp.py のディレクトリを見てみると、「Somedirectory」ファイルができています。
Save できても起動時に Load しなければ意味がないので、起動時に Load するようにします。
speakwin.py 変更前:26 ---------------------------------------------- self.text = ['Hello!, again'] ---------------------------------------------- 変更後:26 ---------------------------------------------- self.text = self.load() ----------------------------------------------
このようにして、self.load したものを self.text に代入するようにします。
もちろん、self.load を書かなければなりません。
speakwin.py 変更後:def save(self) の後に追記 ---------------------------------------------- def load(self): fp = open(self.parent.preffilepath, 'r') import pickle text = pickle.load(fp) fp.close() return text ----------------------------------------------
self.save と逆に、pickle.load を使って、Load したデータを返しているだけです。
MyApp.py を実行すると、先ほど Save したものがリストボックスに表示されます。
SomeDirectory という名前はちょっとおかしいので、「SpeakApp初期設定」みたいな名前にしましょう。そして、白紙のファイルは格好悪いので、初期設定ファイルらしいものにしましょう。
MyApp.py 変更前:74 ---------------------------------------------- preffilepath = ":SomeDirectory" # Location of prefs in Preferences Folder ---------------------------------------------- 変更後:74 ---------------------------------------------- preffilepath = ":SpeakApp初期設定" # Location of prefs in Preferences Folder ----------------------------------------------
ファイルのアイコンは、ファイルタイプを "pref" にすると良いようです。以下のようにして、ファイルタイプを 'pref' にしてみます。
speakwin.py 変更前:58-62 ---------------------------------------------- def save(self): fp = open(self.parent.preffilepath, 'w') import pickle pickle.dump(self.text, fp) fp.close() ---------------------------------------------- 変更後:58- ---------------------------------------------- def save(self): fp = open(self.parent.preffilepath, 'w') import pickle pickle.dump(self.text, fp) fp.close() import macfs #追記 f = macfs.FSSpec(self.parent.preffilepath) #追記 cr, ty = f.GetCreatorType() #追記 f.SetCreatorType(cr, 'pref') #追記 ----------------------------------------------
import macfs
ファイルタイプなどを扱うために、macfs モジュールを使います。
f = macfs.FSSpec(self.parent.preffilepath)
macfs.FSSpec(パス名) で FSSpec オブジェクトというものを作り、f に代入しています。これは、Mac 上のファイルオブジェクトで、Mac独自の操作ができるもの、というふうに私は理解しています。
cr, ty = f.GetCreatorType()
FSSpec オブジェクトである f に対して GetCreatorType() を実行するとクリエータとタイプをタプルで返すので、それぞれ cr、ty に代入します。
f.SetCreatorType(cr, 'pref')
今度は SetCreatorType() で、クリエータとタイプを設定します。クリエータ cr は変更せず、タイプを 'pref' に設定します。
これで、ファイルの保存時に「SpeakApp初期設定」ファイルのアイコンがお馴染みのモノになります。
しかし、ここで MyApp.py を実行すると、『「SeakApp初期設定」ファイルがありません』というエラーがでます。そうでした。起動時に「SeakApp初期設定」を読み込もうとしますが、まだ「SeakApp初期設定」ファイルはできていないのでエラーになります。
そこで、「SeakApp初期設定」がない場合には、処理を省かなければなりません。以下のようにしてみました。
speakwin.py 変更前:68-73 ---------------------------------------------- def load(self): fp = open(self.parent.preffilepath, 'r') import pickle text = pickle.load(fp) fp.close() return text ---------------------------------------------- 変更後:68- ---------------------------------------------- def load(self): try: fp = open(self.parent.preffilepath, 'r') import pickle text = pickle.load(fp) fp.close() except: text = ['Hello!, again'] return text ----------------------------------------------
ファイルが open できなかったら(というより、try 以下でエラーがでたら)、
text = ['Hello!, again']
を実行して text を返す、というふうにしました。
以上のようにして spekawin.py を保存して MyApp.py を実行すると、今度はエラーがなく実行できます。Save してみると、「SpeakApp初期設定」ファイルができていて、アイコンもちゃんと表示されます。
以上の結果をまとめた speak11.sit.bin(約 30k)を作りました。
リストボックスの内容が保存されているのか、わからない状態なので、次回はそれを表示する機能を持たせます。
何か誤りやご質問、お気付きの点、ご意見やご不満などございましたら、メールで、もしくはMacPython BBS(よ)へ書き込んでいただければ幸いです。