ダイアログ


本章では、ダイアログについて触れてみる。


まず、シンプルな物から。

#include <gtk/gtk.h>

static void cb_button(GtkButton *button, gpointer user_data)
{
  GtkWidget *dialog;
  GtkWidget *parent;
  GtkWidget *label;
  gint response;

  parent = GTK_WIDGET(user_data);

  //YES、NOボタン付きのダイアログを生成
  dialog = gtk_dialog_new_with_buttons("Save Confirmation", GTK_WINDOW(parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_NO, GTK_RESPONSE_NO, GTK_STOCK_YES, GTK_RESPONSE_YES, NULL);

  label = gtk_label_new("Confirm are you sure you want to save.");
  //ダイアログにlabelを加える
  gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
  //ダイアログのサイズを設定
  gtk_widget_set_size_request(dialog, 400, 100);
  //ダイアログを表示
  gtk_widget_show_all(dialog);

  //ボタンをクリックした時に戻り値を返す
  response = gtk_dialog_run(GTK_DIALOG(dialog));
  //「はい(Y)」ボタンをクリックした時
  if( response == GTK_RESPONSE_YES ){
    g_print( "Yes button was pressed.\n" );
  }
  //「いいえ(N)」ボタンをクリックした時
  else if( response == GTK_RESPONSE_NO ){
    g_print( "No button was pressed.\n" );
  }
  else{
    g_print( "Another response was received.\n" );
  }
  //ダイアログを閉じる
  gtk_widget_destroy(dialog);
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *entry;
  GtkWidget *button;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Dialog");
  gtk_widget_set_size_request(window, 300, -1);
  gtk_container_set_border_width(GTK_CONTAINER(window), 5);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_container_add(GTK_CONTAINER(window), hbox);

  //「保存(S)」ボタン
  button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button), (gpointer)window);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);

  //「終了(Q)」ボタン
  button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

「保存(S)」ボタンをクリックする。

ダイアログが表示されるので、「いいえ(N)」をクリックしてみる。

きちんと標準出力に表示された。続いて「はい(Y)」もクリックしてみる

これで、Yes or Noダイアログの信号を使えるようになった。


メッセージダイアログ



続いて紹介するのは、メッセージダイアログである。

#include <gtk/gtk.h>

GtkWidget *window;

static void show_dialog(GtkButton *button, gpointer user_data)
{
  GtkWidget *dialog;
  //ボタンタイプ
  GtkButtonsType btype[] = {GTK_BUTTONS_CLOSE, GTK_BUTTONS_OK_CANCEL, GTK_BUTTONS_YES_NO, GTK_BUTTONS_OK};
  //メッセージタイプ
  GtkMessageType mtype = (GtkMessageType)user_data;
  //メッセージ
  gchar *string[] = {"GTK_MESSAGE_INFO", "GTK_MESSAGE_WARNING", "GTK_MESSAGE_QUESTION", "GTK_MESSAGE_ERROR"};
  gint result;

  //メッセージダイアログを生成
  dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, mtype, btype[mtype], "This dialog is a GtkMessageDialog sample\n" "(GtkMessageType = %s)", string[mtype]);
  result = gtk_dialog_run(GTK_DIALOG(dialog));

  switch( result ){
    //「OK(O)」ボタンをクリックした時
    case GTK_RESPONSE_OK:
      g_print( "GTK_RESPONSE_OK is received.\n" );
      break;
    //「キャンセル(C)」ボタンをクリックした時
    case GTK_RESPONSE_CANCEL:
      g_print( "GTK_RESPONSE_CANCEL is received.\n" );
      break;
    //「閉じる(C)」ボタンをクリックした時
    case GTK_RESPONSE_CLOSE:
      g_print( "GTK_RESPONSE_CLOSE is received.\n" );
      break;
    //「はい(Y)」ボタンをクリックした時
    case GTK_RESPONSE_YES:
      g_print( "GTK_RESPONSE_YES is received.\n" );
      break;
    //「いいえ(N)」ボタンをクリックした時
    case GTK_RESPONSE_NO:
      g_print( "GTK_RESPONSE_NO is received.\n" );
      break;
    default:
      g_print( "Another response is received.\n" );
      break;
  }
  gtk_widget_destroy(dialog);
}

int main(int argc, char** argv)
{
  GtkWidget *hbox;
  GtkWidget *button;
  //各種ボタンの役割を指定
  gchar *stock[] = {GTK_STOCK_DIALOG_INFO, GTK_STOCK_DIALOG_WARNING, GTK_STOCK_DIALOG_QUESTION, GTK_STOCK_DIALOG_ERROR};
  int i;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "MessageDialog");
  gtk_container_set_border_width(GTK_CONTAINER(window), 5);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  gtk_container_add(GTK_CONTAINER(window), hbox);

  //左から4種類(情報、警告、質問、エラー)のボタンを生成
  for( i = 0; i < 4; ++i){
    button = gtk_button_new_from_stock(stock[i]);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(show_dialog), GINT_TO_POINTER(i));
    gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  }
  //右端に「終了(Q)」ボタンを生成
  button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

「情報」ボタンをクリックしてみる。

「警告」ボタンをクリックしてみる。

「質問」ボタンをクリックしてみる。

「エラー」ボタンをクリックしてみる。

4種類のダイアログを作成できた。


ファイル選択ダイアログ



第7章で登場したファイル選択ダイアログを使ってみる。

#include <gtk/gtk.h>

static void filter_changed(GtkFileChooserDialog *dialog, gpointer data)
{
  g_print( "File filter changed.\n" );
}

static void cb_button(GtkButton *button, gpointer data)
{
  GtkWidget *dialog;
  GtkWidget *parent;
  GtkEntry *entry;
  GtkFileFilter *filter;
  //GtkFileChooserActionの4通りの選択肢
  GtkFileChooserAction action[] = {GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER};
  gint response;
  gchar *filename;
  gchar *folder;

  parent = GTK_WIDGET(g_object_get_data(G_OBJECT(data), "parent"));
  entry = GTK_ENTRY(data);

  //ファイル選択ダイアログを生成
  dialog = gtk_file_chooser_dialog_new("File Chooser Dialog", GTK_WINDOW(parent), action[0],GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
  filter = gtk_file_filter_new();
  //フィルター名を設定
  gtk_file_filter_set_name(filter, "All Files");
  //フィルターのパターンに*を指定
  gtk_file_filter_add_pattern(filter, "*");
  //フィルターを加える
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

  //JPEG用のフィルターを生成
  filter = gtk_file_filter_new();
  gtk_file_filter_set_name(filter, "JPEG");
  gtk_file_filter_add_mime_type(filter, "image/jpeg");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

  //PNG用のフィルターを生成
  filter = gtk_file_filter_new();
  gtk_file_filter_set_name(filter, "PNG");
  gtk_file_filter_add_mime_type(filter, "image/png");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

  g_signal_connect(dialog, "notify::filter", G_CALLBACK(filter_changed), NULL);

  gtk_widget_show_all(dialog);

  response = gtk_dialog_run(GTK_DIALOG(dialog));
  if( response == GTK_RESPONSE_ACCEPT ){
    //ファイル名を取得
    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
    //フォルダ名を取得
    folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
    g_print( "%s\n", folder);
    g_free(folder);
    //entryにファイル名の文字列を表示
    gtk_entry_set_text(entry, filename);
    g_free(filename);
  }
  else if( response == GTK_RESPONSE_CANCEL ){
    g_print( "Cancel button was pressed.\n" );
  }
  else{
    g_print( "Another response was received.\n" );
  }
  gtk_widget_destroy(dialog);
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *entry;
  GtkWidget *button;

  gtk_init(&argc, &argv);

  window =gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "FileChooser");
  gtk_container_set_border_width(GTK_CONTAINER(window), 5);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  gtk_container_add(GTK_CONTAINER(window), hbox);

  label = gtk_label_new("File:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  //entryを生成
  entry = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  g_object_set_data(G_OBJECT(entry), "parent", (gpointer)window);

  //「開く(O)」ボタンを生成
  button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button), (gpointer)entry);
  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

「開く(O)」ボタンをクリックすると、ファイル選択ダイアログが現れる。

右下のフィルターを「All Files」から「JPEG」に変えてみる。

さらに「PNG」に変えてみる。

適当なファイル(ここでは24c.c)を選択し、「開く(O)」ボタンをクリックする。

entryにファイル名が表示される。


アバウトダイアログ




プログラム名、バージョン、作者などを表示するダイアログのサンプルを作ってみる。

#include <gtk/gtk.h>

static void cb_show_dialog(GtkWidget *widget, gpointer data)
{
  GtkWidget *dialog;
  GtkAboutDialog *about;
  GdkPixbuf *pixbuf;
  gint response;
  //作成者
  const gchar *authors[] = {"author", NULL};
  //ドキュメント担当
  const gchar *documenters[] = {"document", NULL};
  //翻訳担当
  const gchar *translators = "translator";

  dialog = gtk_about_dialog_new();
  about = GTK_ABOUT_DIALOG(dialog);
  //AboutDialogのプログラム名を指定
  gtk_about_dialog_set_program_name(about, "GtkAboutDialog-Sample");
  //作成者を指定
  gtk_about_dialog_set_authors(about, authors);
  //ドキュメント担当を指定
  gtk_about_dialog_set_documenters(about, documenters);
  //翻訳担当を指定
  gtk_about_dialog_set_translator_credits(about, translators);
  //バージョン情報を指定
  gtk_about_dialog_set_version(about, "1.0.0");
  //コピーライトを指定
  gtk_about_dialog_set_copyright(about, "Copyright (C) 2013");
  //コメントを指定
  gtk_about_dialog_set_comments(about, "This is a GtkAboutDialog sample program.");
  //ウェブサイトを指定
  gtk_about_dialog_set_website(about, "http://www9.ocn.ne.jp/~r-ando/index.html");
  gtk_about_dialog_set_website_label(about, "素人の独学GTK+3.0");

  //ロゴを挿入
  pixbuf = gdk_pixbuf_new_from_file("gtk_icon64.png", NULL);
  gtk_about_dialog_set_logo(about, pixbuf);

  gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);

  gtk_widget_show_all(dialog);

  response = gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy(dialog);
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  GtkWidget *button;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "AboutDialog");
  gtk_widget_set_size_request(window, 300, -1);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  button = gtk_button_new_with_label("Show About Dialog");
  gtk_container_add(GTK_CONTAINER(window), button);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_show_dialog), NULL);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

「Show About Dialog」ボタンをクリックする。

アバウトダイアログが表示される。次に「クレジット(R)」ボタンをクリックする。

ちなみに最初のウィンドウの橙字「素人の独学GTK+3.0」をクリックすると、 当サイトのトップページ(HTML5版)が表示される。


前章  | 目次 |  次章



トップ



/