MacPythonについてのページ(よ)>
Python(MyApp) で Mac アプリケーションを作る|目次

第9回 アバウトボックスを作る


このページの目次

Wウィジェットでアバウトボックスを作る
    アバウトボックスのクラスを書く
    MyApp.py にアプリケーション情報を書く
アバウトボックスに色をつける
    文字列も Qd で描く
    アバウトボックスに絵をつける
ここまでのまとめ


Wウィジェットでアバウトボックスを作る

前回は 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 にアプリケーション情報を書く

さらに、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 で描く

先ほどの『これ』の中に文字列を 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)  # 追記
----------------------------------------------

とりあえず、適当に追記してみました。これを実行すると...

Qd.DrawString でアバウトボックス

失敗です。文字は表示されません。そこで、『これ』のように 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)
----------------------------------------------

これを実行してみると、下のようになりました。

drawメソッドを使ってみた

今度は真っ黒です。文字列を描こうと思って RGBForeColor( (0, 0, 0) ) にしてるのが悪いのかなぁ。それなら RGBBackColor で描いている背景も ForeColor で描けばいいのかなぁ、と思って上の Qd.RGBBackColor( (50000, 0, 50000) ) を Qd.RGBForeColor にしてみました。すると...

backcolor にしてみた

おぉ、表示されましたが、改行されてません。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__)
----------------------------------------------

これを実行すると、以下のようになりました。

DrawString のアバウトボックス

ちょっと色がどぎついですが、表示できるようにはなりました。

振り返ってみると、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 で開くと、以下のようになります。

ResEdit で開いたところ

この中の『PICT』をダブルクリックして開きます。

PICT リソースを開いたところ

Resource メニューから『Create New Resource』を選びます。

PICT リソースを新たに作ったところ

PICT リソース ID128 が作られ、上のようなウィンドウが表示されるので、何か適当な画像をこのウィンドウへコピー・ペーストして下さい。手近になければ『情報を見る』で何かのファイルについて表示し、左上のアイコンを選択してコピーし、上のウィンドウでペーストして下さい。

私は昔作ったロゴをペーストしてみました。

PICT リソースに加えた

次に保存して ResEdit を終了します。MyApp.py を実行して、アバウトボックスを表示してみると、以下のように表示されます。

PICT 付のアバウトボックス

ここまでのまとめ

ここまでの MyApp.py と speakwin.py、そして 私の作った画像付きの MyApp.rsrc を一つのフォルダに入れた speak6.sit.bin(約 30k)を作りました。

次は『アバウトボックスをリソースで作る』を書きます。


<▲このページのTOPへ>
戻る   次へ
Python(MyApp) で Mac アプリケーションを作る|目次
MacPythonのページ(よ)トップへ

by ©Hioryuki Yoshimura, 2002-2004.
Last modified at 2004/1/29