Python with Clutter(GNOME3)

Fedora 15 を使っていて GTK+3 をやらない人は何故 Fedora を選んだのだろう。
なんて思っていたけど GNOME 3 の UI は GTK+ だけでは無いようだ。

GNOME 開発センター

Clutter って何だろう。

OpenGLを利用するマルチプラットフォーム対応GUIツールキット「Clutter 1.0」リリース – SourceForge.JP Magazine : オープンソースの話題満載

ようするに Windows の WPF みたいなものかな。
Python からでも使えるようなので試してみよう。
Clutter の所をクリックして coocbook に辿り着く。
まあ当然のごとく C 言語での解説しか無いので Python では自力で漁る。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
from gi.repository import Clutter

def quit(widget):
    Clutter.main_quit()

init = Clutter.init(sys.argv)
if init[0] == Clutter.InitError.SUCCESS:
    stage = Clutter.Stage()
    stage.connect("destroy", quit)
    stage.show()
    Clutter.main()

Python with GTK+ 3 をやったのと同じ感覚で Window が作れた。
Clutter.init は何故かタプルを戻すので最初の値で初期化エラーの確認を行う。
destroy に直接 main_quit を指定すると例外になるので注意。

ExamplePython – ClutterProject

こんなページも見つけたけど Clutter.Stage だけで Window になる。

2. Drawing a shadow under the text

上記をやろうと思ったけど cogl-pango の import 方法が解らない。
でも WPF みたいなものなら opacity で調節してズラしたものを重ねればいいんでない。

5. Making an actor respond to button events

この四角形を利用したボタンもついでに。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
from gi.repository import Clutter

class TestStage(Clutter.Stage):
    def __init__(self):
        Clutter.Stage.__init__(self)
        # Color
        red_full = Clutter.Color.new(0xff, 0x00, 0x00, 0xff)
        red_half = Clutter.Color.new(0xff, 0x00, 0x00, 0x77)
        blue = Clutter.Color.new(0x00, 0x00, 0xff, 0x3f)
        # Text
        self.text1 = Clutter.Text.new_full("Sans 128px", "Text", red_full)
        text2 = Clutter.Text.new_full("Sans 128px", "Text", red_half)
        text2.set_position(6, 4)
        self.add_actor(self.text1)
        self.add_actor(text2)
        # Button (rectangle)
        rect = Clutter.Rectangle.new_with_color(blue)
        rect.set_size(100, 100)
        rect.set_position(20, 30)
        rect.set_reactive(True)
        rect.connect("button-press-event", self.on_click)
        self.add_actor(rect)
        # self
        self.connect("destroy", self.quit)
        self.set_title("Clutter Test")
        self.set_size(300, 200)
        self.show_all()

    def quit(self, widget):
        Clutter.main_quit()

    def on_click(self, actor, event, user_data=None):
        if self.text1.get_text() == "Text":
            self.text1.set_text("Click")
        else:
            self.text1.set_text("Text")

if __name__ == '__main__':
    init = Clutter.init(sys.argv)
    if init[0] == Clutter.InitError.SUCCESS:
        TestStage()
        Clutter.main()

なるほど、やっぱり DirectX 描写の WPF みたいなものだね。
OpenGL 描写の部品を重ねたり直接コールバックを指定できたりで面白い。
でも Button とかの widget クラスは用意されていないみたい。
というか、そういう使い道では無いんだろうね、機会があったら利用しよう。