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 が取得できそうである。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/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 でやってみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #!/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() # 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 にエフェクトが掛かっていたような…
まだ先は長い、リファレンスマニュアル無しで作るのは狂気だがコレが楽しい。