ツールチップ


アイコンをウィジェットの上で停止させた時に、 ウィジェットの説明を表示させる、ツールチップを作成してみる。

#include <gtk/gtk.h>

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

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
  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);

  button =gtk_button_new_from_stock(GTK_STOCK_NEW);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  //ツールチップを設定
  gtk_widget_set_tooltip_text(button, "Run new program");

  button =gtk_button_new_from_stock(GTK_STOCK_OPEN);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  //ツールチップを設定
  gtk_widget_set_tooltip_text(button, "Open a file");

  button =gtk_button_new_from_stock(GTK_STOCK_QUIT);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  //ツールチップを設定
  gtk_widget_set_tooltip_text(button, "Quit this program");

  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

   

マウスのアイコンがPrintScreenに写らなかった。これで、少し表示を親切にできる。


プログレスバー


17章でレベルバーを紹介したが、ここではプログレスバーを紹介する。

#include <gtk/gtk.h>

static gboolean activity_mode = FALSE;
static gboolean show_text = FALSE;
static gboolean inverted = FALSE;
static gint timer = 0;

//100msごとにプログレスバーを変化させる
static gboolean progressbar_update(gpointer user_data)
{
  GtkProgressBar *progressbar = GTK_PROGRESS_BAR(user_data);
  gdouble new_val;
  gchar label[256];

  //アクティブモードでない時
  if( activity_mode == FALSE ){
    gtk_progress_bar_pulse(progressbar);
  }
  //アクティブモードの時
  else{
    new_val = gtk_progress_bar_get_fraction(progressbar) + 0.01;
    //バーが最大まで伸びたら初期状態に戻す
    if( new_val > 1.0 ){
      new_val = 0.0;
    }
    gtk_progress_bar_set_fraction(progressbar, new_val);
    //%表示モードの時
    if( show_text ){
      sprintf( label, "%3d%s", (int)(new_val * 100.0), "%" );
      gtk_progress_bar_set_text(progressbar, label);
    }
  }
  return TRUE;
}

//%表示モードのON、OFF
static void cb_show_text(GtkToggleButton *widget, gpointer user_data)
{
  if( show_text ){
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(user_data), "");
    show_text = FALSE;
    g_print( "show_text:OFF\n" );
  }
  else{
    show_text = TRUE;
    g_print( "show_text:ON\n" );
  }
}

//アクティブモードのON、OFF
static void cb_activity_mode(GtkToggleButton *widget, gpointer user_data)
{
  activity_mode = gtk_toggle_button_get_active(widget);
  if( activity_mode ){
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(user_data), 0.0);
  }
  else{
    gtk_progress_bar_pulse(GTK_PROGRESS_BAR(user_data));
  }
}

//バーを左右どちらに伸ばすか
static void cb_orientation(GtkToggleButton *widget, gpointer user_data)
{
  if( inverted ){
    inverted = FALSE;
    g_print( "inverted:FALSE\n" );
  }
  else{
    inverted = TRUE;
    g_print( "inverted:TRUE\n" );
  }
  gtk_progress_bar_set_inverted(GTK_PROGRESS_BAR(user_data), inverted);
}

//timerを止めて終了
static void cb_quit(GtkButton *widget, gpointer data)
{
  g_source_remove(timer);
  gtk_main_quit();
}

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

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "ProgressBar");
  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(cb_quit), NULL);

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

  progressbar = gtk_progress_bar_new();
  gtk_box_pack_start(GTK_BOX(vbox), progressbar, FALSE, FALSE, 0);

  //%表示ボタン
  button = gtk_check_button_new_with_label("Show Text");
  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_show_text), progressbar);

  //アクティブモード切り替えボタン
  button = gtk_check_button_new_with_label("Activity Mode");
  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_activity_mode), progressbar);

  //伸長方向切り替えボタン
  button = gtk_check_button_new_with_label("Right to Left");
  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_orientation), progressbar);

  //終了ボタン
  button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);

  //100msごとにプログレスバーを変化させる
  timer = g_timeout_add(100, progressbar_update, progressbar);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

「Activity Mode」にチェックを入れると、レベルバーのように最小値から最大値へバーが伸びる。

「Right to Left」にチェックを入れると、右から左へバーが伸びるようになる。

「Show Text」にチェックを入れると、バーに%が表示される

と思いきや、失敗。課題が残った。


スケール


水平スケールを使ったサンプルを作成してみる。

#include <gtk/gtk.h>

//スケールの値が変化した時
static void cb_value_changed(GtkScale *scale, gpointer user_data)
{
  g_print( "value = %f\n", gtk_range_get_value(GTK_RANGE(scale)) );
}

//適用ボタンをクリックした時
static void cb_button(GtkButton *button, gpointer user_data)
{
  g_print( "value = %f\n", gtk_range_get_value(GTK_RANGE(user_data)) );
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *scale;
  GtkWidget *button;
  gdouble min = 0.0, max = 100.0, step = 0.1;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Scale");

  gtk_widget_set_size_request(window, 400, -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, 5);
  gtk_container_add(GTK_CONTAINER(window), hbox);

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

  //水平スケールを生成する(最小0、最大100、ステップ0.1)
  scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step);
  gtk_scale_set_digits(GTK_SCALE(scale), 2);
  gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
  gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_BOTTOM);

  g_signal_connect(G_OBJECT(scale), "value-changed", G_CALLBACK(cb_value_changed), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), scale, TRUE, TRUE, 0);

  button = gtk_button_new_from_stock(GTK_STOCK_APPLY);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button), (gpointer)scale);
  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}





以前はhscaleやvscaleが有ったらしいが、バージョン3.2から廃止され、 水平スケールも垂直スケールも、scaleに統一されたらしい。


前章  | 目次 |  次章



トップ



/