Clutter は魅力的ではあるが描写の全部を自前で用意する必要がある。
つまり GtkButton, GtkListView のような Widget は無い。
それなら ClutterActor を GtkContainer 上に pack できればよくね?
やってみると普通に拒否、全くの別物だからそりゃ当然の話だ。
しかし GNOME3 自体はしっかり連携している。
知らないだけで何か方法があるはずだ。
/usr/lib64/girepository-1.0
をよく見ると GtkClutter というものがある。
Clutter Gtk integration on Vimeo
WPF のような新規ウイジェットではなく GTK+ をエフェクトするみたい。
そりゃ GTK+3 自体が新規だし元から連携していてもおかしくない。
Clutter-Gtk 1.0.2 Reference Manual
どうやら GtkClutterWindow は GtkWindow のサブクラス。
ClutterActor が表面に張り付いている状態って認識でいいのかな?
Python からは get_stage() で ClutterStage が取得できそうである。
#!/usr/bin/env python #-*- coding:utf-8 -*- import sys from gi.repository import Gtk, Clutter, GtkClutter, ClutterX11 def quit(widget, data=None): Gtk.main_quit() #ClutterX11.set_use_argb_visual(True) #ClutterX11.set_display(ClutterX11.get_default_display()) #ClutterX11.disable_event_retrieval() Clutter.init(sys.argv) w = GtkClutter.Window() w.connect("destroy", quit) w.set_title("GtkClutter.Window") w.resize(300, 200) stage = w.get_stage() stage.set_size(300.0, 200.0) w.show_all() Gtk.main()
WARNING 出まくり、初期化とか色々やってみたけど駄目だった。
とりあえず get_stage() だけはできている、使い方が悪いのだろう。
ついでにこの場合 delete-event ではなく destroy 指定でないと終了しない。
直感でやっても上手くいかない、もっと良い方法は無いだろうかと検索。
gtk_clutter_embed_new ()
で作成した Object なら Gtk+ コンテナに入れられるようだ。
試すと上手くいったので ClutterGst でやってみる。
#!/usr/bin/env python #-*- coding:utf-8 -*- import sys from gi.repository import Gtk, Clutter, GtkClutter, ClutterGst class ClutterEmbedTest(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) # Video Texture tx = ClutterGst.VideoTexture() tx.set_uri("file:///home/sasakima-nao/movie/bike/ninjya1000_1.mp4") # Create the Clutter Widget embed = GtkClutter.Embed.new() embed.connect("size-allocate", self.on_size_allocate, tx) # ClutterStage stage = embed.get_stage() stage.add_actor(tx) # Buttons play = Gtk.Button(stock=Gtk.STOCK_MEDIA_PLAY) play.connect("clicked", self.on_play, tx) # packing vbox = Gtk.VBox() vbox.pack_start(embed, True, True, 0) vbox.pack_start(play, False, False, 0) self.add(vbox) self.set_title("ClutterEmbedTest") self.connect("delete-event", self.on_quit) self.show_all() def on_size_allocate(self, widget, allocation, tx): w = widget.get_allocation().width h = widget.get_allocation().height tx.set_size(w, h) def on_play(self, widget, tx): tx.set_playing(True) def on_quit(self, widget, data=None): Gtk.main_quit() if __name__ == '__main__': # initialized Clutter.init(sys.argv) ClutterGst.init(0, "") ClutterEmbedTest() Gtk.main()
よしコレなら何も警告は出ない。
警告が出ないようガンバった WPF 3.0 アプリが 3.5 で無意味にされた過去が…
初心者はワケワカだろうけど、こんな苦労も数年後には無意味になるのでしょう。
やはり親ウインドウサイズに連動しないので size-allocate シグナルを利用。
ClutterActor のサイズは float だけど int のままサイズ変更できた。
コレで GTK+ Widget と ClutterActor の共存アプリケーションができる。
アスペクト比保持とかはどうやるんだろう?
というか最初のビデオでは GTK+ widget にエフェクトが掛かっていたような…
まだ先は長い、リファレンスマニュアル無しで作るのは狂気だがコレが楽しい。