絵の描画

2014年9月7日

ファイル

22-draw.tar.gz

内容

線や矩形などを描画してみましょう。ここでは、描画はウインドウに対して直接に行わず、代りにバックグラウンドの描画領域に対して行い、ウインドウの再描画要求に応じてバックグラウンドの描画領域をウインドウの描画領域に描画する、という手順で実装します。

描画領域として、gtk.DrawingArea を使います。

drawingArea = gtk.DrawingArea()

set_size_request() で描画領域のサイズを指定します。

drawingArea.set_size_request(WIDTH, HEIGHT)

コールバック関数の設定を行います。

drawingArea.connect("configure-event", configure)
drawingArea.connect("expose-event", draw)

"configure-event" はサイズが変更されたときなどに発生します。"expose-event" は再描画要求です。"configure-event" でバックグラウンドの描画領域を作成して描画を行い、"expose-event" でバックグラウンドの描画領域をウインドウの描画領域に描画します。

"configure-event" のコールバック関数内で、バックグラウンドの描画領域 gtk.gdk.Pixmap を作ります。

    pixmap = gtk.gdk.Pixmap(
            drawingArea.window,
            drawingArea.allocation.width,
            drawingArea.allocation.height
    )

実際の描画領域と同じ大きさのものを作ります。もし作成済みであったら、先に参照をはずします。

背景を白で塗りつぶします。

    pixmap.draw_rectangle(
            drawingArea.style.white_gc,
            True,
            0, 0,
            drawingArea.allocation.width,
            drawingArea.allocation.height
    )

draw_rectangle() は、矩形を描画します。drawingArea.style.white_gc は白の "グラフィックコンテキスト" です。グラフィックコンテキストとは、色や線の太さなどの設定のセットです。第 3 引数では、矩形の中を塗りつぶすかどうかを指定します。残りの引数は、矩形の左上端のウインドウ座標と矩形の幅、高さを指定します。

グラフィックコンテキストを取得します。

    gc = drawingArea.style.fg_gc[drawingArea.state]

前景色を指定します。

    color = gtk.gdk.color_parse("#000000")
    gc.set_rgb_fg_color(color)

gtk.gdk.color_parse() では 16 進数で色を指定できます。

set_line_attributes() で線の属性を指定します。

    gc.set_line_attributes(
            1,
            gtk.gdk.LINE_SOLID,
            gtk.gdk.CAP_NOT_LAST,
            gtk.gdk.JOIN_MITER
    )

第 2 引数は線の太さです。第 3 引数に gdk.LINE_ON_OFF_DASH を指定すると、線が点線になります。

draw_point() で、指定した座標に点を打ちます。

    for i in range(0, HEIGHT, 10):
        pixmap.draw_point(gc, 10, i)

draw_line() で、指定した始点・終点を結ぶ線を引きます。

    for i in range(0, 60, 20):
        pixmap.draw_line(
                drawingArea.style.black_gc,
                20, 20 + i,
                100, 50 - i
        )

drawingArea.style.black_gc は黒のグラフィックコンテキストです。

draw_rectangle() の第 3 引数に False を渡すと、線で矩形が描かれます。

    pixmap.draw_rectangle(
            gc,
            False,
            50, 90,
            100, 50
    )

gdk_draw_arc() で円弧を描くことができます。

    pixmap.draw_arc(
            gc,
            True,
            70, 180,
            100, 100,
            0, 120*64
    )

第 3 引数は塗りつぶしの指定です。第 4 〜 7 引数で円弧の境界の矩形領域を指定し、第 8, 9 引数で角度の視点・終点を指定しています。角度は 1/64 度単位なので、120 度を指定したい場合は 120*64 を入力します。

draw_polygon() で多角形を描くことができます。

    pixmap.draw_polygon(
            gc,
            False,
            [
                (170, 20),
                (180, 80),
                (230, 100),
                (260, 60),
                (240, 15)
            ]
    )

第 3 引数は塗りつぶしの指定、第 4 引数は点の配列です。

テキストの描画には pango.Layout を使います。pango.Layout は次のように作ります。

    layout = drawingArea.create_pango_layout("")

フォントの指定には pango.FontDescription を使います (pango モジュールのインポートが必要)。

    fontDesc = pango.FontDescription("sans 18")
    layout.set_font_description(fontDesc)

layout にテキストを設定し、draw_layout() でテキストを描画します。

    layout.set_text("Text")
    pixmap.draw_layout(gc, 230, 130, layout)

"expose-event" のコールバック関数で、以下のように、バックグラウンドの描画領域 (pixmap) をウインドウの描画領域 (drawingArea) に描画します。

def draw(drawingArea, event):
    drawingArea.window.draw_drawable(
            drawingArea.style.fg_gc[drawingArea.state],
            pixmap,
            event.area.x, event.area.y,
            event.area.x, event.area.y,
            event.area.width, event.area.height
    )

PyGTK プログラミング 目次へ