「GNOMEフレームワーク」の版間の差分

削除された内容 追加された内容
gnome-panelの設定例を追加しました。
M 目次のレベルを変更しました。
148 行
上の例はmmmという名のメニューを作成し、それをクリックしたときlllと書かれたメニューを表示し、更にその中のlllと書かれた部分をクリックすることで関数menu_cbを実行するというプログラムです。メニューの項目は増やせるので、コールバック関数をいろいろなアプリケーションの起動を行う関数とすることで、ランチャーの役目を果たすアプリケーションとすることができます。
 
=====ポップリケメニュションの起動=====
 
gnome-panelではパネルの各所を右クリックすることでポップアップメニューを得ることができます。この操作はGUIを使った操作としてはよく見られるもので、どのように実現されるかが気になる所です。実は、この操作はGTK+のクラスであるGtkMenuの操作として典型的なものです。ここではGtkMenuのポップアップの例を見るとともに、実際にこの操作がどのようにgnome-panel中で用いられているかを見て行きます。
 
GtkMenuのポップアップの例として、次のサンプルをあげます。
int main (int argc, char **argv){
gtk_init(&argc, &argv);
GtkWidget *menuitem, *menu;
/* メニューの例を参照 */
menu = gtk_menu_new();
menuitem = gtk_menu_item_new_with_label("lll");
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menu_cb), NULL );
gtk_widget_show_all(menu);
/* ウィンドウから離れてメニューを表示*/
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
gtk_get_current_event_time() );
/*メインループ*/
gtk_main();
return 0;
}
:[[画像:gnome_panel_gtk_menu_popup_no_window.svg]]
上の例では"lll"と書き込まれたメニューを作成した後、そのメニューをgtk_menu_popupによって表示します。メニューが表示される場所はgtk_menu_popupの引数によって変更できるのですが、上の例ではgtk_menu_popupが実行された時点でのマウスカーソルの場所になります。実行例を見るとわかるのですがこの例は何も無い部分に突然メニューが表示されるため、やや非直観的です。普通の例ではGtkWindow等のマウスイベントを設定し,マウスのボタンが押されたときにメニューが表示されるようにします。ただし、GtkWindowは通常ではマウスのボタンに対応するイベントを持たないため,その点を補う必要があります。 このためには、gtk_widget_add_eventsかGtkEventBoxを使う方法がありますが、ここではgtk_widget_add_eventsを用いる方法を述べます。GtkEventBoxについてはGTK+のリファレンス等を参照してください。以降の説明ではある程度[[Xプログラミング]]の経験があると理解が容易になります。
 
gtk_widget_add_eventsはウィジェットがGTK+の背後で動いているウィンドウシステムから、新しいイベントを得るように設定する関数です。背後のウィンドウシステムの代表例は[[w:X Window System]]ですがUnix系のシステムでないなら他のものになることもあります。GTKではウィンドウシステムの値を直接使わなくてもすむよう、[[w:GDK]]というライブラリを用いています。GDKはGTK+とともに配布されるライブラリです。
 
gtk_widget_add_eventsでは引数として(GtkWidget *, GdkEventMask)を取ります。ここで、EventMask(イベントマスク)は対応するイベントをXなどから受け取るかを定めるビット列です。例えば,Xを用いてイベントを処理する場合にはXSelectInputなどを用いますが,この関数の引数としてイベントマスクが用いられます。詳しくは[[Xプログラミング]]を参照してください。ここで扱うGdkEventMaskも同種の値です。
 
実際にマウスボタンのイベントを見るには,GdkEventMaskとしてGDK_BUTTON_PRESS_MASKを用います。結局GtkWindowを作った後,
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
を実行すると,ウィンドウ内でマウスボタンの操作を見ることができるようになります。この関数の後には,GTKのイベントである"button_press_event"を用いてマウスのボタンを扱うことができます。
 
ここまでのことを用いて,メニューを作成してからメインループに至るまでの部分は次のようになります。
GtkWindow *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
g_signal_connect(window, "button_press_event", G_CALLBACK(window_button_cb), menu);
gtk_widget_show(window);
ただし、menuは上で作成したGtkMenuと同一です。ここで、window_button_cbは次のように与えます。
void window_button_cb(GtkWidget *window, GdkEventButton *button, GtkWidget *menu){
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
gtk_get_current_event_time() );
}
:[[画像:gnome_panel_gtk_menu_popup_with_window.svg]]
 
 
=====アプリケーションの起動=====
 
アプリケーションの起動を行うためには、 コールバック関数として定義された関数(上の例ではmenu_cbと与えられている)の中で、新たな"プロセス"を作る必要があります。"プロセス"はOSが複数のアプリケーションを同時に動かすときの単位で、それを作る方法はOSによって異なっています。Unix系のOSではプロセスを作る関数は大抵[[w:fork]]と呼ばれます。forkはプロセスを作成し、新たに作成されたプロセスのIDを返します。また、作成されたプロセスで実際にあるアプリケーションを起動する関数として、Unix系のOSではexec系の関数が与えられます。execは与えられる引数によっていくつかの似た関数が提供されます。
248 ⟶ 294行目:
-->
 
=====gnome-panelでのgconf=====
 
ここまででgconfの基本的な使い方を見て来ました。gnome-panelでもパネル内のどの位置にどのオブジェクトが配置されているかなどをを記録するために、gconfを用いています。ここではまず、gnome-panelがどのようにgconfdから設定を受け取り、設定への変更を取得しているかを見て行きます。
 
=====gnome-panelの起動=====
 
ここではgnome-panelがどのように起動するかを見て行きます。通常のアプリケーションと同様、gnome-panelは起動時に設定を参照してどこにオブジェクトを配置するかなどを決めます。この設定は設定ファイルではなく、gconfを用いて行われるのですが、ここでは実際にアプリケーションの起動時にどのようにgconfが用いられているかを見て行きます。
 
267 ⟶ 312行目:
具体的には追加されたオブジェクトが"メニューバー"だった場合にはpanel_menu_bar_load_from_gconfを呼んでいます。この関数は設定に従って対応する"メニューバー"オブジェクトを作成する関数です。この関数の詳細を追うこともできますが、一応gconfの設定を読んだ後に、設定に応じて各種のオブジェクトを与える過程が得られたので、アプリケーションの起動に限った話はここまでとします。
 
=====各種設定の変更=====
 
ここまでで、gnome-panelが起動するときに、gconfが与える設定に従って、各種ウィジェットを見分ける方法を見て来ました。実際にはgnome-panelはgnome-panelが動作している最中に設定が変更されても、それに対応してウィジェットを作成する機構を持っています。これはgconfの機能を活用した機構です。
372 ⟶ 417行目:
 
ここまででgconfの設定をアプリケーションの動作中に反映するための機構を見て来ました。これらはアプリケーションの起動時にしか変更を反映できない方法と比べて優れた方法です。同様の方法は他のGNOMEアプリケーションでも用いられており、gconfがGNOMEのライブラリとして重要であることを示しています。
 
====ポップアップメニュー====
 
gnome-panelではパネルの各所を右クリックすることでポップアップメニューを得ることができます。この操作はGUIを使った操作としてはよく見られるもので、どのように実現されるかが気になる所です。実は、この操作はGTK+のクラスであるGtkMenuの操作として典型的なものです。ここではGtkMenuのポップアップの例を見るとともに、実際にこの操作がどのようにgnome-panel中で用いられているかを見て行きます。
 
GtkMenuのポップアップの例として、次のサンプルをあげます。
int main (int argc, char **argv){
gtk_init(&argc, &argv);
GtkWidget *menuitem, *menu;
/* メニューの例を参照 */
menu = gtk_menu_new();
menuitem = gtk_menu_item_new_with_label("lll");
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menu_cb), NULL );
gtk_widget_show_all(menu);
/* ウィンドウから離れてメニューを表示*/
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
gtk_get_current_event_time() );
/*メインループ*/
gtk_main();
return 0;
}
:[[画像:gnome_panel_gtk_menu_popup_no_window.svg]]
上の例では"lll"と書き込まれたメニューを作成した後、そのメニューをgtk_menu_popupによって表示します。メニューが表示される場所はgtk_menu_popupの引数によって変更できるのですが、上の例ではgtk_menu_popupが実行された時点でのマウスカーソルの場所になります。実行例を見るとわかるのですがこの例は何も無い部分に突然メニューが表示されるため、やや非直観的です。普通の例ではGtkWindow等のマウスイベントを設定し,マウスのボタンが押されたときにメニューが表示されるようにします。ただし、GtkWindowは通常ではマウスのボタンに対応するイベントを持たないため,その点を補う必要があります。 このためには、gtk_widget_add_eventsかGtkEventBoxを使う方法がありますが、ここではgtk_widget_add_eventsを用いる方法を述べます。GtkEventBoxについてはGTK+のリファレンス等を参照してください。以降の説明ではある程度[[Xプログラミング]]の経験があると理解が容易になります。
 
gtk_widget_add_eventsはウィジェットがGTK+の背後で動いているウィンドウシステムから、新しいイベントを得るように設定する関数です。背後のウィンドウシステムの代表例は[[w:X Window System]]ですがUnix系のシステムでないなら他のものになることもあります。GTKではウィンドウシステムの値を直接使わなくてもすむよう、[[w:GDK]]というライブラリを用いています。GDKはGTK+とともに配布されるライブラリです。
 
gtk_widget_add_eventsでは引数として(GtkWidget *, GdkEventMask)を取ります。ここで、EventMask(イベントマスク)は対応するイベントをXなどから受け取るかを定めるビット列です。例えば,Xを用いてイベントを処理する場合にはXSelectInputなどを用いますが,この関数の引数としてイベントマスクが用いられます。詳しくは[[Xプログラミング]]を参照してください。ここで扱うGdkEventMaskも同種の値です。
 
実際にマウスボタンのイベントを見るには,GdkEventMaskとしてGDK_BUTTON_PRESS_MASKを用います。結局GtkWindowを作った後,
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
を実行すると,ウィンドウ内でマウスボタンの操作を見ることができるようになります。この関数の後には,GTKのイベントである"button_press_event"を用いてマウスのボタンを扱うことができます。
 
ここまでのことを用いて,メニューを作成してからメインループに至るまでの部分は次のようになります。
GtkWindow *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
g_signal_connect(window, "button_press_event", G_CALLBACK(window_button_cb), menu);
gtk_widget_show(window);
ただし、menuは上で作成したGtkMenuと同一です。ここで、window_button_cbは次のように与えます。
void window_button_cb(GtkWidget *window, GdkEventButton *button, GtkWidget *menu){
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
gtk_get_current_event_time() );
}
:[[画像:gnome_panel_gtk_menu_popup_with_window.svg]]