Wウィジェットでアバウトボックスを作る
アバウトボックスのクラスを書く
MyApp.py にアプリケーション情報を書く
アバウトボックスに色をつける
文字列も Qd で描く
アバウトボックスに絵をつける
ここまでのまとめ
前回は EasyDialogs.Message を使った簡単なダイアログボックスを作る、というか、文字列を変更しただけだったので、今回は Wウィジェットを使ったダイアログボックスを作ってみます。
speakwin.py を書いてアプリケーションのメインのウィンドウを作ったように、新たに about.py ファイルを作って、そこにアバウトボックスのウィンドウを書いていきます。
speakwin.py もそうなんですが、MyApp.py の中に書いてもいいんです。でも、別ファイルにしておくと、あとから変更したりするときにきれいかな、と思います。
MyApp.py と同じフォルダ内(前回までの結果 speak4.sit.bin を使っていきます)に作ります。
about.py ---------------------------------------------- import W import MyApp ABOUT_TEXT = MyApp.__appname__ + ' ' + MyApp.__version__ + '\r by ' + MyApp.__author__ + '\r ' + MyApp.__date__ class AboutBox(W.Dialog): # アバウトボックス def __init__(self): W.Dialog.__init__(self, (200, 200), title = "About %s..." % MyApp.__appname__) self.text = W.TextBox((10,10,-10,-100), text = ABOUT_TEXT, fontsettings = ("Osaka", 0, 12, (0,0,0))) self.closeButton = W.Button((20,-30,50,20), title = "OK", callback = self.close) self.setdefaultbutton(self.closeButton) self.open() ----------------------------------------------
import W
Wウィジェットの Dialog を使ってダイアログボックスを使うので、当然インポートします。
import MyApp
次の行(About)でアバウトボックスに表示する文字列を設定します。アプリケーションの情報は MyApp.py に書いて一元管理しといたほうが便利なので、この about モジュールは MyApp をインポートして、その情報を使います。どういうことかというと、次の行の...
TEXT = MyApp.__appname__ + ' ' + MyApp.__version__ + '\r by ' + MyApp.__author__ + '\r ' + MyApp.__date__
このように、MyApp.py に書かれた『__appname__ = "SpeakApp"』なんかを使うわけです。__version__、__author__、__date__ は、後ほど MyApp.py に書き加えましょう。
次にアバウトボックスのクラスです。
class AboutBox(W.Dialog):
# アバウトボックス
このアプリケーションのメインのウィンドウは W.Windouw を継承しました。AboutBox では W.Dialog を継承します。W.Dialog は EasyDialogs.Message に似ていますが、W.Window のようにボタンを加えたりできます。W.Window を継承してもいいのですが、W.Dialog は次のようにポジション/サイズの指定のところでサイズ(要素2個のタプル)しか指定できないんですが、画面の真ん中に表示してくれるんです。アバウトボックス向きでしょ。
def __init__(self):
W.Dialog.__init__(self, (200, 200), title = "About %s..." % MyApp.__appname__)
コンストラクタです。W.Dialog はサイズとタイトルしか引数をとりません。ウィンドウのタイトルとして MyApp.__appname__ を使って『About SpeakApp...』と表示されるようにしています。
self.text = W.TextBox((10,10,-10,-100), text = ABOUT_TEXT, fontsettings = ("Osaka", 0, 12, (0,0,0)))
表示するテキストをテキストボックスで作っています。ポジションサイズにマイナスがありますが、(ウィンドウの左端から10、上端から10、右端から10、下端から100)の意味です。ここで ABOUT_TEXT を使っています。
self.closeButton = W.Button((20,-30,50,20), title = "OK", callback = self.close)
ダイアログボックスを閉じるためのボタンを作っています。ここでもポジションサイズにマイナスを使って、ウィンドウの下端から 30 がボタンの上端になるようにしています。コールバックの self.close はスーパークラスのメソッドを呼び出すので、このクラスで記述する必要はありません。
self.setdefaultbutton(self.closeButton)
以前、使いましたね。ボタンが縁取りされて return、enter キーで押されます。
self.open()
ウィンドウを開きます。
さらに、MyApp.py に __version__ などを書かなければなりません。
MyApp.py 64- に追記 ---------------------------------------------- __appname__ = "SpeakApp" __version__ = "0.1" __author__ = "Yoshimura" __date__ = "2002/07/17" ----------------------------------------------
前回書いた __appname__ に続けて上のように書きます。__author__ や日付はご自由に書いて下さい。
以上のように about.py を書き、MyApp.py を訂正して保存し、MyApp.py を実行して Apple メニューから『SpeakApp について...』を選ぶと、下のように表示されます。
ここまでの MyAppp.py、speakwin.py、about.py、そして MyApp.rsrc を一つのフォルダに入れた speak5.sit.bin(約 30k)を作りました。
アバウトボックスはこれでもいいのですが、何となくアバウトボックスっぽくありません。普通のアバウトボックスは、他のウィンドウと違って色がついていたり、アプリケーションのアイコンが表示されたりします。
そこで、手始めにウィンドウに色を付けてみます。
でも、Wリファレンスには、色を付ける方法は書いていません。私は Pythonmania にあったソースで色をつける方法を知りました。そのソースに私がちょっと書き加えたのが 『これ』です。これは MyApp.py みたいに Wウィジェットに必要なリソース類を備えていないので、ブラウザでテキスト形式で「別名で保存...」して、PythonIDE で開いて実行して下さい。
要するに、Qd モジュールを使うといいみたいです。
about.py __init__ メソッド末尾に加える ---------------------------------------------- possize = self.getpossize() import Qd Qd.RGBBackColor( (50000, 0, 50000) ) Qd.PaintRect((0,0,possize[0],possize[1])) ----------------------------------------------
possize = self.getpossize()
アバウトボックス自身のポジション/サイズを得て、代入しています。ここでは AboutBox はW.Dialog を継承したものなので、サイズ (200, 200) のタプルを返します。speakwin.Win についてこれを実行するとポジション/サイズのタプル (10, 40, 250, 180) を返します。
import Qd
Qd.RGBBackColor( (50000, 0, 50000) )
Qd モジュールをインポートしてます。次に色の設定で、Qd.RGBBackColor を使っています。先ほどの『これ』では、Qd.RGBForeColor を使っていましたが、ここでは Qd.RGBBackColor を使います。Qd.RGBForeColor を使うと、一瞬色が描かれますが、すぐ真っ白になってしまいます。
MacPython2.2以降をお使いの場合は『import Qd』の代わりに『from Carbon import Qd』にしてください。(2004/01/29)
Qd.PaintRect((0,0,possize[0],possize[1]))
ウィンドウを色付けする、つまりちょうどウィンドウの大きさ(0, 0, 200, 200)で矩形を描きます。W.Window を継承しているクラスのインスタンスについて実行する場合は、possize が (10, 40, 250, 180) のようになっているので、Qd.PaintRect((0,0,possize[2],possize[3])) とします。
以上の about.py で実行すると、以下のようなアバウトボックスが表示されます。
うーーん。ちょっと失敗です。テキストボックスのところが真っ白のままです。テキストボックスを使うとその背景が白になっちゃいます。それなら文字列も Qd で描いてみましょう。
先ほどの『これ』の中に文字列を Qd.DrawString で描いているところがあります。それをまねて描いてみます。
about.py AboutBox クラス ---------------------------------------------- class AboutBox(W.Dialog): # アバウトボックス def __init__(self): W.Dialog.__init__(self, (200, 200), title = "About %s..." % MyApp.__appname__) self.closeButton = W.Button( (20,-30,50,20), title = "OK", callback = self.close) self.setdefaultbutton(self.closeButton) self.open() possize = self.getpossize() import Qd Qd.RGBBackColor( (50000, 0, 50000) ) Qd.PaintRect((0,0,possize[0],possize[1])) Qd.RGBForeColor( (0, 0, 0) ) # 追記 Qd.MoveTo(10, 20) # 追記 Qd.TextSize(12) # 追記 Qd.DrawString(ABOUT_TEXT) # 追記 ----------------------------------------------
とりあえず、適当に追記してみました。これを実行すると...
失敗です。文字は表示されません。そこで、『これ』のように draw メソッドを使ってみます。
about.py AboutBox クラス ---------------------------------------------- class AboutBox(W.Dialog): # アバウトボックス def __init__(self): W.Dialog.__init__(self, (200, 200), title = "About %s..." % MyApp.__appname__) self.closeButton = W.Button( (20,-30,50,20), title = "OK", callback = self.close) self.setdefaultbutton(self.closeButton) self.open() def draw(self, visRgn = None): # 追記して以下をメソッドで実行 possize = self.getpossize() import Qd Qd.RGBBackColor( (50000, 0, 50000) ) Qd.PaintRect((0,0,possize[0],possize[1])) Qd.RGBForeColor( (0, 0, 0) ) Qd.MoveTo(10, 20) Qd.TextSize(12) Qd.DrawString(ABOUT_TEXT) ----------------------------------------------
これを実行してみると、下のようになりました。
今度は真っ黒です。文字列を描こうと思って RGBForeColor( (0, 0, 0) ) にしてるのが悪いのかなぁ。それなら RGBBackColor で描いている背景も ForeColor で描けばいいのかなぁ、と思って上の Qd.RGBBackColor( (50000, 0, 50000) ) を Qd.RGBForeColor にしてみました。すると...
おぉ、表示されましたが、改行されてません。Qd.DrawString はDraw というくらいだから、"\r" のようなものを判断しないんでしょうね。そこで以下のようにしてみます。
about.py AboutBox クラス ---------------------------------------------- class AboutBox(W.Dialog): # アバウトボックス def __init__(self): W.Dialog.__init__(self, (200, 200), title = "About %s..." % MyApp.__appname__) self.closeButton = W.Button( (20,-30,50,20), title = "OK", callback = self.close) self.setdefaultbutton(self.closeButton) self.open() def draw(self, visRgn = None): possize = self.getpossize() import Qd Qd.RGBForeColor( (50000, 0, 50000) ) Qd.PaintRect((0,0,possize[0],possize[1])) Qd.RGBForeColor( (0, 0, 0) ) Qd.MoveTo(10, 20) Qd.TextSize(12) Qd.DrawString(MyApp.__appname__ + " " + MyApp.__version__) Qd.MoveTo(40, 45) Qd.DrawString("by " + MyApp.__author__) Qd.MoveTo(40, 70) Qd.DrawString(MyApp.__date__) ----------------------------------------------
これを実行すると、以下のようになりました。
ちょっと色がどぎついですが、表示できるようにはなりました。
振り返ってみると、draw メソッドはきっと自動的に呼び出されて Qd 関係のことをやってくれるんでしょうね、たぶん。
よく見ると、フォントも違っています。フォントを設定するには Qd.TextSize(12) のあとにフォントの設定を書きます。
about.py AboutBox クラス ---------------------------------------------- ・ ・ ・ Qd.TextSize(12) import Fm # 追記 font = Fm.GetFNum("Osaka") # 追記 Qd.TextFont(font) # 追記 Qd.DrawString(MyApp.__appname__ + " " + MyApp.__version__) ・ ・ ・ ----------------------------------------------
Qd には Qd.TextFont というメソッドがあるのですが、引数はフォント ID ナンバーらしいです。そのため、Fm(フォントマネージャ)モジュールをインポートして、"Osaka" フォントの ID を調べ、それを Qd.TextFont に引数として渡しています。
MacPython2.2以降をお使いの場合は『import Fm』の代わりに『from Carbon import Fm』にしてください。(2004/01/29)
このへんのこと、例えば Fm モジュールのようにドキュメントのないモジュールの使用法などについて知るのに、私は Python2.1 以降に付属の pydoc で調べたり、__doc__ なんかを PythonIDE のモジュールブラウザで調べています。Python2.0 でもPython2.1 の pydoc.py と inspect.py を Python2.0 の Lib フォルダなんかに入れると使えます。PythonInterpreter で「>>> import pydoc」「>>> pydoc.help()」「help > Fm」を実行します。また、オプションキーを押したまま pydoc.py を PythonInterpreter にドロップして Unix-like command line に -w Fm を打ち込んで実行すると、Fm モジュールの関数の __doc__ をまとめた Fm.html というファイルを pydoc.py と同じディレクトリに作ってくれます。以前は自作の pydoc みたいなものを使ってました。それでもわからないことがあると、C のソースを見ます(見ても私にはわからないことが多いですが)。
Qd を使ったので、ついでにアバウトボックスに絵を付けましょう。
about.py の AboutBox クラスの draw メソッドの最後に以下を加えます。
about.py AboutBox クラス ---------------------------------------------- class AboutBox(W.Dialog): ・ ・ ・ def draw(self, visRgn = None): ・ ・ ・ picHr = Qd.GetPicture(128) # 追記 x = 60; y = 80 # 追記 Qd.DrawPicture(picHr, (x, y, x + 120, y + 64)) # 追記 ----------------------------------------------
picHr = Qd.GetPicture(128)
これは、リソースファイルの PICT リソースの ID128 のハンドラを得て、変数 picHr に代入しています。詳しい意味は私は理解していません。
x = 60; y = 80
画像を表示する座標を x、y に代入しています。場所を微調整し易いように x、y を使ってここで代入しました。
Qd.DrawPicture(picHr, (x, y, x + 120, y + 64))
picHr の画像を ポジション/サイズの位置に表示します。サイズのところで x、y に足す数値を変えると、それに合わせて拡大/縮小されます。
上で『リソースファイルの PICT リソースの ID128 のハンドラを得て』と書きました。リソースファイルに PICT リソースとして画像を準備しなければなりません。
リソースファイル『MyApp.rsrc』を ResEdit で開いて画像を加えます。ResEdit (クリックでダウンロードできます)を持っていなければ編集できません。
リソースファイル『MyApp.rsrc』を ResEdit で開くと、以下のようになります。
この中の『PICT』をダブルクリックして開きます。
Resource メニューから『Create New Resource』を選びます。
PICT リソース ID128 が作られ、上のようなウィンドウが表示されるので、何か適当な画像をこのウィンドウへコピー・ペーストして下さい。手近になければ『情報を見る』で何かのファイルについて表示し、左上のアイコンを選択してコピーし、上のウィンドウでペーストして下さい。
私は昔作ったロゴをペーストしてみました。
次に保存して ResEdit を終了します。MyApp.py を実行して、アバウトボックスを表示してみると、以下のように表示されます。
ここまでの MyApp.py と speakwin.py、そして 私の作った画像付きの MyApp.rsrc を一つのフォルダに入れた speak6.sit.bin(約 30k)を作りました。
次は『アバウトボックスをリソースで作る』を書きます。