2012-01-08 15 views
3

私はインターフェイス用のGTKライブラリを使ってCのゲームを書いています。このアイデアは、ボタンを保持するためのものと、ユーザに設定をさせるための他のウィジェットと、実際のゲームプレイ中に画像を表示したり移動させるための2つの主要なコンテナを有することである。メニューウィジェットを保持するためのVBoxと、ゲームスプライトを保持するFixedコンテナを使用しています。私のボタンのアクションのいずれかでC Gtk問題:メインウィンドウにVBoxを追加する

GtkWidget* vbox; 
GtkWidget* fixed; 
... 
int main(int argc, char** argv) { 
// (The rest of this code block is in the main method) 
... 
// Make a vertical box for the menu widgets. 
vbox = gtk_vbox_new(TRUE, 0); 

// Add the menu widgets to the vbox. 
gtk_box_pack_start(GTK_BOX(vbox), label1, TRUE, TRUE, 0); 
gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0); 
gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0); 
gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 0); 

// Make a new fixed container, which allows its children 
// widgets to be moved dynamically. 
fixed = gtk_fixed_new(); 

// Add the game widgets to the fixed container. 
gtk_fixed_put(GTK_FIXED(fixed), player1, x, y); 
gtk_fixed_put(GTK_FIXED(fixed), player2, x, y + 40); 
gtk_fixed_put(GTK_FIXED(fixed), ball, x + 80, y); 
gtk_fixed_put(GTK_FIXED(fixed), wall, x + 120, y); 

// Add the fixed container to the window. 
gtk_container_add(GTK_CONTAINER(window), vbox); 

gtk_widget_show(vbox); 
gtk_widget_show(fixed); 

、私はゲームプレイを開始するには、以下があります:

私はここでのVBoxに関連するコードの行のすべてとmain()メソッドで固定のコンテナを持っています
gtk_container_remove(GTK_CONTAINER(window), vbox); 
gtk_container_add(GTK_CONTAINER(window), fixed); 

問題なく動作します。ただし、一定の条件が満たされた後、私は反対をしてと呼ばれる別の関数、持っている:

gtk_container_remove(GTK_CONTAINER(window), fixed); 
gtk_container_add(GTK_CONTAINER(window), vbox); 

をこれには、次の問題が発生します。

(a.out:11762): Gtk-CRITICAL **: IA__gtk_container_add: assertion `GTK_IS_WIDGET (widget)' failed 

私はウィジェット階層を見て、確認しましたそのVBoxはGtkWidgetのカテゴリに分類されます。上記のエラーは、最初にVBoxをmain()メソッドのウィンドウに追加したときには発生しませんでした。 gtk_main()が呼び出された後、このコンテナをウィンドウに追加する際に気付かないことがありますか?

答えて

3

GtkWidgetsは参照数ですが、あなたは参照を所有していません。これは、ウィジェットが見える限り、ウィンドウシステムはそれらへの参照を1つ保持するため、GtkWidgetsでは通常です。しかし、コンテナからウィジェットを削除している限り、参照カウントはゼロになり、破棄されます。

浮動の参照があるため、ウィジェットが最初に作成された直後に存在するため、初めて動作します。

あなたの最も簡単な解決策は、浮動参照を実際のものに変換するように作成した直後に、という2つの移動ウィジェットへの参照を保持することです。しかし、完了したらg_object_unrefに電話することを忘れないでください!

その他のオプションは、単に/インクリメントあなたの周りにそれらを移動している間、カウンタをデクリメントするだろうが、あなたはまだ期待通りに動作するようにfixedへの参照をシンクする必要があります。そして、

g_object_ref_sink(fixed); 

g_object_ref(vbox); 
gtk_container_remove(GTK_CONTAINER(window), vbox); 
gtk_container_add(GTK_CONTAINER(window), fixed); 
g_object_unref(fixed); 

そして:固定容器への浮動参照がディませんでしたどのように来る

g_object_ref(fixed); 
gtk_container_remove(GTK_CONTAINER(window), fixed); 
gtk_container_add(GTK_CONTAINER(window), vbox); 
g_object_unref(vbox); 
+0

e gtk_main()の呼び出しの後に?フローティングリファレンスは、ウィジェットがウィンドウに追加されるまで周りに固定されますか? –

+1

'gtk_main'の呼び出しは参照に何もしません。そして、浮動参照は、沈んでしまうまで固執します( 'g_object_ref_sink()')。通常、コンテナに追加される最初の(通常は唯一の)時間が沈められます。 – rodrigo

関連する問題