Entryの文字列をLabelに出力


やっと、Visual Basicの第1章に入った観がある。 Entryに入力した文字列を、「Enter」ボタンをクリックして、Labelに表示させてみる。 今回は構造体を使って、ウィジェットを動作させてみた。 ウィジェットの配置にはvboxとhboxを使った。

#include <gtk/gtk.h>

//構造体でウィジェットを指定する
typedef struct main_dialog_type {
  GtkWidget *window;
  GtkWidget *button1;
  GtkWidget *button2;
  GtkWidget *entry;
  GtkWidget *label;
  GtkWidget *vbox;
  GtkWidget *hbox;
} MainDialog;

//Enterボタンをクリックして、Labelの文字を変える
static void cb_button_clicked1(GtkWidget *widget, gpointer data)
{
  const gchar *text;
  char buf[256];

  //*textをEntryのtext格納先と指定する
  text = gtk_entry_get_text(GTK_ENTRY(((MainDialog*)data)->entry));
  //bufに*textの文字列を格納する
  sprintf(buf, "%s", text);
  //bufの文字列をLabelのtextに設定する
  gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label), buf);
}

static void cb_button_clicked2(GtkWidget *button2, gpointer user_data)
{
  gtk_main_quit();
}

int main(int argc, char **argv)
{
  //構造体変数名をdialogと宣言
  MainDialog dialog;

  gtk_init(&argc, &argv);

  //構造体変数名.メンバ名で記載
  dialog.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request(dialog.window,300,200);
  gtk_window_set_title(GTK_WINDOW(dialog.window), "Entry & Label");
  gtk_window_set_position(GTK_WINDOW(dialog.window), GTK_WIN_POS_CENTER);
  gtk_container_set_border_width(GTK_CONTAINER(dialog.window), 10);

  dialog.vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
  gtk_container_add(GTK_CONTAINER(dialog.window), dialog.vbox);

  //EntryとLabelを配置
  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.entry = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.entry, TRUE, TRUE, 0);
  dialog.label = gtk_label_new("blank");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.label, TRUE, TRUE, 0);

  //Enterボタンを配置
  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.button1 = gtk_button_new_with_label("Enter");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.button1, TRUE, TRUE, 0);
  g_signal_connect(dialog.button1, "clicked", G_CALLBACK(cb_button_clicked1), &dialog);

  //Quitボタンを配置
  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.button2 = gtk_button_new_with_label("Quit");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.button2, TRUE, TRUE, 0);
  g_signal_connect(dialog.button2, "clicked", G_CALLBACK(cb_button_clicked2), NULL);

  g_signal_connect(dialog.window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show_all(dialog.window);
  gtk_main();

  return 0;
}


文字を入力して「Enter」ボタンをクリックすると、


Labelの"blank"という文字が、Entryに入力した文字と同じになる。


簡単な電卓


2つのEntryに入力された数値を、ComboBoxTextで指定した加減乗除で計算する、 簡単な電卓を作ってみる。

#include <gtk/gtk.h>
#include <string.h>

typedef struct main_dialog_type {
  GtkWidget *window;
  GtkWidget *button1;
  GtkWidget *button2;
  GtkWidget *label1;
  GtkWidget *entry1;
  GtkWidget *comboboxtext;
  GtkWidget *entry2;
  GtkWidget *label2;
  GtkWidget *vbox;
  GtkWidget *hbox;
} MainDialog;

  //Calculateボタンがクリックされると動作する関数
static void cb_button_clicked1(GtkWidget *widget, gpointer data)
{
  const gchar *text1;
  const gchar *text2;
  unsigned int buf1;
  unsigned int buf2;
  unsigned int buf3 = 0;
  char *act;
  char text3[256];
  //計算する条件が揃っているかのフラッグ
  gboolean calc = TRUE;
  text1 = gtk_entry_get_text(GTK_ENTRY(((MainDialog*)data)->entry1));
  //Entry1の入力数値をbuf1に格納
  sscanf(text1, "%d", &buf1);
  printf( "buf1:%d\n", buf1 );
  text2 = gtk_entry_get_text(GTK_ENTRY(((MainDialog*)data)->entry2));
  //Entry2の入力数値をbuf2に格納
  sscanf(text2, "%d", &buf2);
  printf( "buf2:%d\n", buf2 );
  act = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(((MainDialog*)data)->comboboxtext));
  printf( "act:%s\n", act );
  //ComboBoxTextのリストから選択されているか確認
  if( act == NULL ){
    gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label2), "ComboBoxから選択して下さい");
    calc = FALSE;
  }
  //buf1が適正値か確認
  if( buf1 > 255 || buf1 < 1 ){
    gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label2), "Entry1の入力が不適切です");
    calc = FALSE;
  }
  //buf2が適正値か確認
  if( buf2 > 255 || buf2 < 1 ){
    gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label2), "Entry2の入力が不適切です");
    calc = FALSE;
  }
  //問題が無ければ計算結果をbuf3に格納
  if( calc == TRUE ){
    if( !strcmp( act, "+" ) ){
      buf3 = buf1 + buf2;
    }
    else if( !strcmp( act, "-" ) ){
      buf3 = buf1 - buf2;
    }
    else if( !strcmp( act, "*" ) ){
      buf3 = buf1 * buf2;
    }
    else if( !strcmp( act, "/" ) ){
      buf3 = buf1 / buf2;
    }
    else if( !strcmp( act, "%" ) ){
      buf3 = buf1 % buf2;
    }
    //ここに来ることは無いはずだが、念のため
    else{
      gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label2), "エラー");
    }
  printf( "buf3:%d\n", buf3 );
  //計算結果をLabel2に表示する
  sprintf(text3, "%d", buf3);
  gtk_label_set_text(GTK_LABEL(((MainDialog*)data)->label2), text3);
  }
  if( calc == TRUE ){
    printf( "calc:TRUE\n" );
  }
  else if( calc == FALSE ){
    printf( "calc:FALSE\n" );
  }
  else{
    printf( "calc:ERROR\n" );
  }
}

static void cb_button_clicked2(GtkWidget *button2, gpointer user_data)
{
  gtk_main_quit();
}

int main(int argc, char **argv)
{
  MainDialog dialog;

  gtk_init(&argc, &argv);

  dialog.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request(dialog.window,300,200);
  gtk_window_set_title(GTK_WINDOW(dialog.window), "Entry & Label");
  gtk_window_set_position(GTK_WINDOW(dialog.window), GTK_WIN_POS_CENTER);
  gtk_container_set_border_width(GTK_CONTAINER(dialog.window), 10);

  dialog.vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
  gtk_container_add(GTK_CONTAINER(dialog.window), dialog.vbox);

  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.label1 = gtk_label_new("1〜255の正数をそれぞれ入力して下さい");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.label1, TRUE, TRUE, 0);

  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.entry1 = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.entry1, TRUE, TRUE, 0);
  //ComboBoxTextを作成、配置する
  dialog.comboboxtext = gtk_combo_box_text_new();
  //ComboBoxTextのリストに項目を追加する
  gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(dialog.comboboxtext), 0, NULL, "+");
  gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(dialog.comboboxtext), 1, NULL, "-");
  gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(dialog.comboboxtext), 2, NULL, "*");
  gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(dialog.comboboxtext), 3, NULL, "/");
  gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(dialog.comboboxtext), 4, NULL, "%");
  //ComboBoxTextのデフォルト文字を0(+)に指定
  gtk_combo_box_set_active(GTK_COMBO_BOX(dialog.comboboxtext), 0);
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.comboboxtext, TRUE, TRUE, 0);
  dialog.entry2 = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.entry2, TRUE, TRUE, 0);

  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.button1 = gtk_button_new_with_label("Calculate");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.button1, TRUE, TRUE, 0);
  g_signal_connect(dialog.button1, "clicked", G_CALLBACK(cb_button_clicked1), &dialog);

  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.label2 = gtk_label_new("blank");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.label2, TRUE, TRUE, 0);

  dialog.hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start(GTK_BOX(dialog.vbox), dialog.hbox, TRUE, TRUE, 0);
  dialog.button2 = gtk_button_new_with_label("Quit");
  gtk_box_pack_start(GTK_BOX(dialog.hbox), dialog.button2, TRUE, TRUE, 0);
  g_signal_connect(dialog.button2, "clicked", G_CALLBACK(cb_button_clicked2), NULL);

  g_signal_connect(dialog.window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show_all(dialog.window);
  gtk_main();

  return 0;
}

緑文字は、イージーミスでコンパイルは通るものの、動作がおかしかった為に、 デバッグ用に使っていた名残である。実行結果は、下図のようになる。

コンボ・ボックス・テキストに初期文字を入れて置くに当たり、 コンボ・ボックスとしてgtk_combo_box_set_activeが使用できる。 さらに、Entry1とEntry2に数値を入力して、下図のようになる。

「Calculate」ボタンをクリックすると、計算結果がラベル2に表示される。

簡単ではあるが、計算ができるようになった。次章では、メニュー・バーを使ってみたい。


前章  | 目次 |  次章



トップ



/