UP | HOME

はじめの一歩

簡単な例

まず、非常に簡単な例から始めることにしましょう。 最初のスクリプトは小さなウィンドウを表示するだけです。 それ以上のことは何もしません。 1行1行じっくり分析していきます。 以下にコードを示します。

#! /usr/bin/env python

# simple.py

import wx

app = wx.App()

frame = wx.Frame(None, -1, 'simple.py')
frame.Show(True)

app.MainLoop()
#!/usr/bin/env python

# simple.py

最初の1行は、Pythonインタープリタへのパスが書かれているシバンです。 2行目はコメントで、スクリプトファイルの名前が書かれています。

import wx

この行でwxPythonの基本モジュールを読み込んでいます。 core, controls, gdi, misc, windowsの5つです。 技術的なことを言うとwxとは名前空間です。 基本モジュールの全ての関数とオブジェクトは、 wx.というプレフィックス(接頭辞)から始まります。 次の行ではアプリケーションのオプジェクトを生成します。

app = wx.App()

wxPythonプログラムは必ず一つのアプリケーションオブジェクトを持っていなければいけません。

frame = wx.Frame(None, -1, 'simple.py')
frame.Show(True)

wx.Frameオブジェクトを生成しました。 wx.Frameは重要なコンテナウィジェットで、後ほどじっくり分析していきます。 wx.Frameは他のウィジェットの親で、それ自体は親を持ちません。 親パラメータとして None を指定したとき、そのウィジェットは親を持たないということになります。 つまり、wx.Frameはウィジェットの階層で頂点に当たります。 wx.Frameウィジェットを作ったあとは、必ず Show() メソッドを呼び出してスクリーンに表示しなければなりません。

app.MainLoop()

最後の行で、メインループに入っていきます。 メインループは終わりのないサイクルです。 アプリケーションが生きているあいだに発生する全てのイベントを受け取り、片付けていきます。

これは非常にシンプルな例です。 しかしその簡潔さにもかかわらず、非常に多くの事をこのウィンドウで行うことが可能です。 ウィンドウのサイズを変更したり、最大最小化したりできます。 本来ならば、こうした機能はとても多くのコードを必要とします。 ですがそのコード全ては、wxPythonツールキットによって隠蔽され、標準機能として提供されているのです。 車輪の再発明をする必要はありません。

./img/simple.jpg

wx.Frame

wx.FrameウィジェットはwxPythonの中で最も重要なウィジェットの一つです。 wx.Frameはコンテナウィジェットですから、他のウィジェットを格納することができます。 フレームやダイアログ以外のあらゆるウィンドウを格納することができます。 wx.Frameはタイトルバー、枠線と中央のコンテナエリアから構成されています。 タイトルバーと枠線はオプションなので、さまざまなフラグによって取り除くことができます。

wx.Frameは以下のようなコンストラクタを持っています。 ご覧の通り、7つの引数を取ります。 最初のパラメータはデフォルト値を持ちませんので、必ず与えてください。 他の6つはデフォルト値を持ちます。 これら引数のうち初めの3つは必須で、残り4つは任意です。

wx.Frame(wx.Window parent, int id=-1, string title='', wx.Point pos=wx.DefaultPosition, 
         wx.Size size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, string name="frame")

wx.DEFAULT_FRAME_STYLE はデフォルトフラグ( wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN )をまとめたものです。 色々なスタイルを組み合わせていくことで、wx.Frameウィジェットのスタイルを変更できます。 以下に短い例を示します。

#! /usr/bin/env python

# nominimizebox.py

import wx

app = wx.App()
window = wx.Frame(None, style=wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
                  | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
window.Show(True)

app.MainLoop()

最小化ボタンを表示しないようにするため、最小化フラグを設定していません。

./img/nominimizebox.png

サイズと位置

アプリケーションのサイズを設定する方法は2通りあります。 ウィジェットのコンストラクタにサイズを引数として渡すか、 SetSize() メソッドを呼び出すかです。

#! /usr/bin/env python

# size.py

import wx

class Size(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 200))
        
        self.Show(True)


app = wx.App()
Size(None, -1, 'size.py')
app.MainLoop()

wx.Frame.__init__(self, parent, id, title, size=(250, 200))

コンストラクタで、wx.Frameウィジェットの幅を250px、高さを200pxに設定しました。

同じように、スクリーン上でのアプリケーションの位置を指定することもできます。 デフォルトでは、ウィンドウはスクリーンの左上端に置かれます。 しかし、これはOSプラットフォームやウィンドウマネージャによっても変わる可能性があります。 いくつかのウィンドウマネージャは自分自身でアプリケーションの位置を決めます。 アプリケーションが重ならない様に、なんらかの最適化をかけるのです。 プログラマはウィンドウの位置をコード上で指定することができます。 wx.Frameウィジェットのコンストラクタにposという変数がありました。 デフォルト以外の値を与えることで、ウィンドウの位置を制御できます。

メソッド詳細
Move(wx.Point point)ウィンドウを与えられた位置に移動します
MoveXY(int x, int y)ウィンドウを与えられた位置に移動します
SetPosition(wx.Point point)ウィンドウの位置を設定します
SetDimensions(wx.Point point, wx.Size size)ウィンドウの位置とサイズを設定します

これらを行うメソッドは様々です、どれを使っても構いません。コインの裏表で決めちゃってください:-)

#! /usr/bin/env python

# move.py

import wx

class Move(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        
        self.Move((100, 100))
        self.Show(True)


app = wx.App()
Move(None, -1, 'move.py')
app.MainLoop()

ウィンドウを最大化して表示したいという状況があったとします。 この場合ウィンドウは(0, 0)に配置され、スクリーン全体を占めます。 wxPythonは内部的にスクリーン座標を計算するので、単に Maximize() メソッドを呼ぶだけで最大化できます。 アプリケーションをスクリーン中央に配置したければ、wxPythonはとても便利なメソッドを備えています。 Centre() メソッドは簡単にウィンドウを中央に配置します。 スクリーンの幅や高さを計算する必要はなく、メソッドを呼び出すだけで良いのです。

#! /usr/bin/env python

# centre.py

import wx

class Centre(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        self.Centre()
        self.Show(True)

app = wx.App()
Centre(None, -1, 'centre.py')
app.MainLoop()

ウィジェット間の通信

ウィジェットがアプリケーションと通信する方法について知っておくのは大切です。 次の例をご覧ください。

#! /usr/bin/env python

# communicate.py

import wx

class LeftPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)

        self.text = parent.GetParent().rightPanel.text

        button1 = wx.Button(self, -1, '+', (10, 10))
        button2 = wx.Button(self, -1, '-', (10, 60))

        self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId())
    
    def OnPlus(self, event):
        value = int(self.text.GetLabel())
        value = value + 1
        self.text.SetLabel(str(value))
    
    def OnMinus(self, event):
        value = int(self.text.GetLabel())
        value = value - 1
        self.text.SetLabel(str(value))

class RightPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
        self.text = wx.StaticText(self, -1, '0', (40, 60))

class Communicate(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(380, 200))

        panel = wx.Panel(self, -1)
        self.rightPanel = RightPanel(panel, -1)

        leftPanel = LeftPanel(panel, -1)
        
        hbox = wx.BoxSizer()
        hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 5)
        hbox.Add(self.rightPanel, 1, wx.EXPAND | wx.ALL, 5)

        panel.SetSizer(hbox)
        self.Centre()
        self.Show(True)

app = wx.App()
Communicate(None, -1, 'communicate.py')
app.MainLoop()

この例では2つのパネルを使用しています。 右と左のパネルです。 左のパネルは2つのボタンを持ち、右のパネルは1つのテキストを持ちます。 ボタンを押すことでテキストに表示される数字を変更することができます。 問題はテキストへの参照を取得する方法です。

もし全てのウィジェットが同一クラスにあれば、これは難しくありません。 しかし、ウィジェットが異なるクラスとして生成されている場合はどうでしょうか? こういう場合は、ヒエラルキーを通して参照を取得しなければなりません。

panel = wx.Panel(self, -1)
self.rightPanel = RightPanel(panel, -1)

leftPanel = LeftPanel(panel, -1)

右パネルは左パネルより先に定義 しなければならない ことに注意してください。 なぜなら左パネルを構築している間に、右パネルで定義されたテキストを探すからです。 存在しないウィジェットの参照を得ることはできません。

self.text = parent.GetParent().rightPanel.text

さて、答え合わせです。 ウィジェットはそれぞれに親を持ちます。 この例では、親は左右のパネルを表示するパネルが親になります。 parent.GetParent() を呼び出すことで、フレームウィジェットへの参照を得ることができます。 フレームウィジェットは右パネルへの参照を持っています。 そして右パネルはテキストウィジェットへの参照を持っているのです。

./img/communicate.jpg

The original page is here.

Date: 2010-10-28 19:49:00 JST

HTML generated by org-mode 6.36c in emacs 23