Notebookウィジェット


Notebookウィジェットを使うことで、同一ウィンドウ上に、複数のテーマを持った画面を表示できる。 サンプルを作ってみる。

#include <gtk/gtk.h>

GtkWidget *notebook;
gint pos = 2;
gboolean show_t = TRUE;
gboolean show_b = TRUE;

//プログラムを終了する
static void cb_button1_clicked(GtkWidget *button1, gpointer user_data)
{
  gtk_main_quit();
}

//次のページに移動する
static void cb_button2_clicked(GtkWidget *button2, gpointer user_data)
{
  gtk_notebook_next_page(GTK_NOTEBOOK(notebook));
}

//前のページに移動する
static void cb_button3_clicked(GtkWidget *button3, gpointer user_data)
{
  gtk_notebook_prev_page(GTK_NOTEBOOK(notebook));
}

//タブの表示位置を変更する
static void cb_button4_clicked(GtkWidget *button4, gpointer user_data)
{
  ++pos;
  if( pos >= 4 ){
    pos = 0;
  }
  if( pos == 0 ){
    gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT);
  }
  else if( pos == 1 ){
    gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_RIGHT);
  }
  else if( pos == 2 ){
    gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
  }
  else if( pos == 3 ){
    gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
  }
}

//タブとボーダーのON/OFF
static void cb_button5_clicked(GtkWidget *button5, gpointer user_data)
{
  if( show_t == TRUE && show_b == TRUE ){
    show_t == FALSE;
  }
  else if( show_t == FALSE && show_b == TRUE ){
    show_t == TRUE;
    show_b == FALSE;
  }
  else if( show_t == TRUE && show_b == FALSE ){
    show_t == FALSE;
  }
  else{
    show_t == TRUE;
    show_b == TRUE;
  }

  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), show_t);
  gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), show_b);
}

//表示しているページの削除
static void cb_button6_clicked(GtkWidget *button6, gpointer user_data)
{
  gint page;
  //現在表示しているページ番号を取得
  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
  //表示中のページを削除
  gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page);
  //ページを再描画
  gtk_widget_draw(GTK_WIDGET(notebook), NULL);
}

int main( int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *frame;
  GtkWidget *label;
  GtkWidget *button1;
  GtkWidget *button2;
  GtkWidget *button3;
  GtkWidget *button4;
  GtkWidget *button5;
  GtkWidget *button6;
  GtkWidget *checkbutton;
  GtkWidget *grid;

  int i;
  char bufferf[32];
  char bufferl[32];

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Notebook");
  //今回はウィジェットを多く使うので、指定サイズより大きくなる
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

  grid = gtk_grid_new();
  gtk_container_add(GTK_CONTAINER(window), grid);

  notebook = gtk_notebook_new();
  gtk_notebook_set_tab_pos(GTK_NOTEBOOK (notebook), GTK_POS_TOP);
  gtk_grid_attach(GTK_GRID(grid), notebook, 0, 0, 6, 1);
  gtk_widget_show(notebook);
  gtk_container_set_border_width(GTK_CONTAINER(notebook), 10);

  //Pageのappend(Page1からPage5を表示)
  for(i = 0; i < 5; i++){
    sprintf(bufferf, "Append Frame %d", i + 1);
    sprintf(bufferl, "Page %d", i + 1);

    frame = gtk_frame_new(bufferf);
    gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
    gtk_widget_set_size_request(frame, 100, 75);
    gtk_widget_show(frame);

    label = gtk_label_new(bufferf);
    gtk_container_add(GTK_CONTAINER(frame), label);
    gtk_widget_show(label);

    label = gtk_label_new(bufferl);
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
  }

  //PageのPrepend(PPage5からPPage1を前部へ挿入し、古いページは6ページ以降にスライド
  for(i=0; i < 5; i++){
    sprintf(bufferf, "Prepend Frame %d", i + 1);
    sprintf(bufferl, "PPage %d", i + 1);

    frame = gtk_frame_new(bufferf);
    gtk_container_set_border_width (GTK_CONTAINER(frame), 10);
    gtk_widget_set_size_request(frame, 100, 75);
    gtk_widget_show(frame);

    label = gtk_label_new(bufferf);
    gtk_container_add(GTK_CONTAINER(frame), label);
    gtk_widget_show(label);

    label = gtk_label_new(bufferl);
    gtk_notebook_prepend_page(GTK_NOTEBOOK(notebook), frame, label);
  }

  //別のページを挿入する
  checkbutton = gtk_check_button_new_with_label("CheckButton");
  gtk_widget_set_size_request(checkbutton, 100, 75);
  gtk_widget_show(checkbutton);
  label = gtk_label_new ("Add page");
  //挿入されるのは3ページ目(checkbuttonとlabelを含む)
  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), checkbutton, label, 2);

  //初期ページを4ページ目に設定
  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 3);

  button1 = gtk_button_new_with_label ("close");
  g_signal_connect(GTK_BUTTON(button1), "clicked", G_CALLBACK(cb_button1_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button1, 0,1,1,1);
  gtk_widget_show(button1);

  button2 = gtk_button_new_with_label ("next page");
  g_signal_connect(GTK_BUTTON(button2), "clicked", G_CALLBACK(cb_button2_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button2, 1,1,1,1);
  gtk_widget_show(button2);

  button3 = gtk_button_new_with_label ("prev page");
  g_signal_connect(GTK_BUTTON(button3), "clicked", G_CALLBACK(cb_button3_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button3, 2,1,1,1);
  gtk_widget_show(button3);

  button4 = gtk_button_new_with_label ("tab position");
  g_signal_connect(GTK_BUTTON(button4), "clicked", G_CALLBACK(cb_button4_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button4, 3,1,1,1);
  gtk_widget_show(button4);

  button5 = gtk_button_new_with_label ("tabs/border on/off");
  g_signal_connect(GTK_BUTTON(button5), "clicked", G_CALLBACK(cb_button5_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button5, 4,1,1,1);
  gtk_widget_show(button5);

  button6 = gtk_button_new_with_label ("remove page");
  g_signal_connect(GTK_BUTTON(button6), "clicked", G_CALLBACK(cb_button6_clicked), NULL);
  gtk_grid_attach(GTK_GRID(grid), button6, 5,1,1,1);
  gtk_widget_show(button6);

  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show(grid);
  gtk_widget_show(window);

  gtk_main();

  return 0;
}

最初に4ページ目のPPage3が表示された。

最後に付け加えた3ページ目も、きちんと表示されている。

「next page」ボタンで、後方のページを表示して行く。

「prev page」ボタンで、前方のページを表示して行く。
「tab position」ボタンで、タブの位置を変えてみる。 デフォルトで「GTK_POS_TOP」に設定した。

次のクリックで「GTK_POS_BOTTOM」に変更。

次のクリックで「GTK_POS_LEFT」に変更。

次のクリックで「GTK_POS_RIGHT」に変更。

tabとborderをTRUEとFALSEに切り替えてみたが、特に変化が見られない。 Frameのように、OSによるのだろうか?

「remove」ボタンをクリックすると、表示されているページを消去する事ができる。 しかし、標準出力にエラーが表示される。

現在、ページを削除するプログラムを作成する予定が無いので、しばらく放置させていただく。 allocの文字に、何となく領域開放の雰囲気を感じる。
次章では、CheckButtonウィジェットを使ってみたい。


前章  | 目次 |  次章



トップ



/