![]() |
![]() |
![]() |
メニュバーの表示
さて、メニューバーを表示させるサンプル・プログラムを作成してみたが、 vboxの上段に表示されるはずのメニューバーが現れない。 しかし、コンパイルは通るし、コアダンプも無い。 思い出した。Ubuntu11.10以降はウィンドウを広く使うため、 メニュバーは画面の左上にマウスのアイコンを移した時に、表示されるんだった。 しかし、それでは説明しづらいので、メニューバーをウィンドウ内に戻してみた。 所が、Firefoxの起動に不具合が出たので、やむなく元に戻した。 よって、Ubuntu流に説明するしかない。 4章のvboxでは上にスクロール付きイメージ、下にボタンを配置してみたが、 今回は上にメニューバー、下にスクロールバー付きイメージを表示する。
|
#include <gtk/gtk.h> #include <stdlib.h> //Openメニューが選択された時に呼び出される関数
static void cb_open(GtkAction *action, gpointer user_data){ //内容はまだ未処理のまま
g_print("This function isn't implemented yet.\n");} //Quitメニューが選択された時に呼び出される関数
static void cb_quit(GtkAction *action, gpointer user_data){ GObject *window = G_OBJECT(user_data); //uiは共用データkeyの名称である
g_object_unref(g_object_get_data(window, "ui"));gtk_main_quit(); } //メニューの構造をXML形式で記述
static const gchar *menu_info ="<ui>" " <menubar name='Menubar'>" " <menu name='File' action='File'>" " <menuitem name='Open' action='Open'/>" " <separator/>" " <menuitem name='Quit' action='Quit'/>" " </menu>" " </menubar>" "</ui>"; //メニューアイテムの詳細情報
static GtkActionEntry entries[] = {{"File", NULL, "_File"}, {"Open", GTK_STOCK_OPEN, "_Open", "<control>O", "Open an image", G_CALLBACK(cb_open)}, {"Quit", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit this program", G_CALLBACK(cb_quit)}, }; //メニューを作成する関数
static GtkUIManager* create_menu(GtkWidget *parent){ GtkUIManager *ui; GtkActionGroup *actions; //UIマネージャの作成
ui = gtk_ui_manager_new(); //アクショングループの作成
actions = gtk_action_group_new("menu"); //アクショングループにメニューアイテムの詳細情報を追加
gtk_action_group_add_actions(actions, entries, sizeof(entries) / sizeof(entries[0]), parent); //アクショングループをUIマネージャに登録
gtk_ui_manager_insert_action_group(ui, actions, 0); //メニュー構成情報をUIマネージャに登録
gtk_ui_manager_add_ui_from_string(ui, menu_info, -1, NULL); //ウィンドウ上でメニューアイテムのショートカットキーを有効にする設定
gtk_window_add_accel_group(GTK_WINDOW(parent), gtk_ui_manager_get_accel_group(ui));return ui; } int main(int argc, char** argv) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window, 300, 200); { GtkWidget *vbox; vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); gtk_container_add(GTK_CONTAINER(window), vbox); { //GTK UIマネージャ
GtkUIManager *ui; //メニューバー・ウィジェット
GtkWidget *menubar;GtkWidget *scroll_window; //ウィンドウ上にメニューを作成
ui = create_menu(window); //ウィンドウに"ui"という識別子でUIマネージャを登録
g_object_set_data(G_OBJECT(window), "ui", (gpointer)ui); //メニューバーを取得
menubar = gtk_ui_manager_get_widget(ui, "/Menubar"); //メニュバーをvboxに配置
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);scroll_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0); { GtkWidget *image; image = gtk_image_new_from_file("goshikinuma.jpg"); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_window), image); } } } gtk_widget_show_all(window); gtk_main(); return 0; } |
Fileをクリックすると、
| Open | Ctrl+O | |
| Quit | Ctrl+Q |
という項目が現れ、両項目の間にはXML部分の<separator/>タグによって、 境界線が引かれている。XML部分だが、例えば
|
static const gchar *menu_info = "<ui>" " <menubar name='Menubar'>" " <menu name='File' action='File'>" " <menuitem name='Open' action='Open'/>" " <separator/>" " <menuitem name='Quit' action='Quit'/>" " </menu>" " <menu name='Edit' action='Edit'>" " <menuitem name='Copy' action='Copy'/>" " <menuitem name='Paste' action='Paste'/>" " </menu>" " </menubar>" "</ui>"; |
と記述し、関連動作部分の変更を行えば、メニューバーの項目を
| File | Edit | ||||
| ┣Open | Ctrl+O | ┣Copy | Ctrl+C | ||
| ┗ Quit | Ctrl+Q | ┗ Paste | Ctrl+V | ||
と変化させる事もできる。
ファイル選択ダイアログ
難しいUIマネージャを使ったのだから、ファイルの参照くらいはしておきたい。 次のサンプルは、新しくダイアログを表示させ、選択した画像ファイルを、 スクロールバー付きウィンドウに表示させる物である。
|
#include <gtk/gtk.h> #include <stdlib.h> //イメージ・ウィジェットはあちこちで使うので、ここで宣言
GtkWidget *image;static void cb_open(GtkAction *action, gpointer user_data) { GtkWidget *window; GtkWidget *dialog; gint response; window = GTK_WIDGET(user_data); //ファイル選択ダイアログを作成
dialog = gtk_file_chooser_dialog_new("Open an image file", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); //ファイル選択ダイアログを表示
gtk_widget_show_all(dialog); //ファイル選択処理を開始
response = gtk_dialog_run(GTK_DIALOG(dialog)); //ファイル選択処理が終了した戻り値を受け取ったら
if( response == GTK_RESPONSE_ACCEPT){gchar *filename; //選択したファイル名を取得
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); //取得したファイル名から画像を表示
gtk_image_set_from_file(GTK_IMAGE(image), filename); //ファイル名取得に確保したメモリ領域を開放
g_free(filename);} //ファイル選択ダイアログを閉じる
gtk_widget_destroy(dialog);} static void cb_quit(GtkAction *action, gpointer user_data) { GObject *window = G_OBJECT(user_data); g_object_unref(g_object_get_data(window, "ui")); gtk_main_quit(); } static const gchar *menu_info = "<ui>" " <menubar name='Menubar'>" " <menu name='File' action='File'>" " <menuitem name='Open' action='Open'/>" " <separator/>" " <menuitem name='Quit' action='Quit'/>" " </menu>" " </menubar>" "</ui>"; static GtkActionEntry entries[] = { {"File", NULL, "_File"}, {"Open", GTK_STOCK_OPEN, "_Open", "<control>O", "Open an image", G_CALLBACK(cb_open)}, {"Quit", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit this program", G_CALLBACK(cb_quit)}, }; static GtkUIManager* create_menu(GtkWidget *parent) { GtkUIManager *ui; GtkActionGroup *actions; GError *gErrors = NULL; ui = gtk_ui_manager_new(); actions = gtk_action_group_new("menu"); gtk_action_group_add_actions(actions, entries, sizeof(entries) / sizeof(entries[0]), parent); gtk_ui_manager_insert_action_group(ui, actions, 0); gtk_ui_manager_add_ui_from_string(ui, menu_info, -1, NULL); gtk_window_add_accel_group(GTK_WINDOW(parent), gtk_ui_manager_get_accel_group(ui)); return ui; } int main(int argc, char** argv) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window, 300, 200); { GtkWidget *vbox; vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); gtk_container_add(GTK_CONTAINER(window), vbox); { GtkUIManager *ui; GtkWidget *menubar; GtkWidget *scroll_window; ui = create_menu(window); g_object_set_data(G_OBJECT(window), "ui", (gpointer)ui); menubar = gtk_ui_manager_get_widget(ui, "/Menubar"); gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); scroll_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0); { //今回、初期表示画像は無し
image = gtk_image_new();gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_window), image); } } } gtk_widget_show_all(window); gtk_main(); return 0; } |
ファイル選択ダイアログを作成した時に、「開く(O)」ボタンと「キャンセル(C)」ボタンを作成していた。
dialog = gtk_file_chooser_dialog_new("Open an image file", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
ここで、第3引数にGTK_FILE_CHOOSER_ACTION_OPENを選択しているが、
GtkFileChooseActionには
| GTK_FILE_CHOOSER_ACTION_OPEN | ファイルを開く | |
| GTK_FILE_CHOOSER_ACTION_SAVE | ファイルを保存 | |
| GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER | フォルダを選択 | |
| GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER | フォルダを作成 |
の4種類が有る。実際に、ファイルを開いてみる。
少し難しかったが、ファイル選択ダイアログが使えるようになった。 次は時間経過から、タイマー機能を使うプログラムを作ってみたい。