GTK3   コントロール

ホーム   C/C++チュートリアル


コントロール


ボタン

button.c


#include <gtk/gtk.h>

void activate();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    app     =   gtk_application_new ("jp.vivacocoa.button",     0   );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *button;
    
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),    "Button");
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    
    button  =
    gtk_button_new_with_label       ("Quit");
    gtk_widget_set_size_request     (button,    100,    -1          );
    gtk_widget_set_halign           (button,    GTK_ALIGN_CENTER    );
    gtk_widget_set_valign           (button,    GTK_ALIGN_CENTER    );
    gtk_container_add               (GTK_CONTAINER(window), button  );
    
    g_signal_connect_swapped        (button,    "clicked",
                                     G_CALLBACK(gtk_widget_destroy),
                                     window);
    
    gtk_widget_show_all             (window);
}
    

Quit ボタンをクリックしてもアプリケーションが終了します。

コード説明


チェックボタン

checkbutton.c


#include <gtk/gtk.h>

void activate();
void toggle_title();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.chekcbutton", 0  );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *check;
    
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),
                                        "CheckButton" );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    
    check   =
    gtk_check_button_new_with_label ("Show title");
    gtk_widget_set_halign           (check, GTK_ALIGN_CENTER);
    gtk_widget_set_valign           (check, GTK_ALIGN_CENTER);
    gtk_toggle_button_set_active    (GTK_TOGGLE_BUTTON(check),  TRUE);
    gtk_container_add               (GTK_CONTAINER(window), check   );
    
    g_signal_connect                (check, "clicked",
                                     G_CALLBACK(toggle_title),
                                     window                         );
    
    gtk_widget_show_all             (window);
}

void toggle_title(GtkWidget *widget, gpointer window)
{
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
        gtk_window_set_title(window, "CheckButton");
    else
        gtk_window_set_title(window, ""           );
}
	

実行結果


チェックボタンがチェックされていれば、ウィンドウのタイトルは表示されます。
チェックボタンがチェックされていなければ、ウィンドウのタイトルは表示されません。

macOSの場合、チェックボタンとラジオボタンを使った場合に、 実行時に次のような警告が出ることがありますが、結果には影響ありません。


(a.out:713): Gtk-WARNING **: 07:26:23.142: Could not load a pixbuf
from /org/gtk/libgtk/theme/Adwaita/assets/check-symbolic.svg.
This may indicate that pixbuf loaders or the mime database could not be 
found.
    

コード説明

  1. check = gtk_check_button_new_with_label("Show title");
    gtk_check_button_new_with_label( )関数でチェックボタンを作ります。 引数にはチェックボタンに表示する文字列を指定します。
  2. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
    gtk_toggle_button_set_active( )関数で チェックボタンなどの状態を設定できます。引数は次のとおりです。
    1. 第1引数にGTK_TOGGLE_BUTTON( )マクロで囲んでウィジェットを指定します
    2. 第2引数にTRUEかFALSEを指定します。TRUEを指定すると 第1引数のウィジェットがアクティブ状態(チェックされている状態)になります。
  3. g_signal_connect(check, "clicked", G_CALLBACK(toggle_title), window);
    g_signal_connect( )関数でイベントとイベントハンドラーを接続します。 引数は次のとおりです。
    1. 第1引数にイベントを発するウィジェットを指定します
    2. 第2引数にイベントの種類を指定します。 チェックボタンがクリックされた時のイベントは "clicked" です
    3. 第3引数にイベントハンドラーを指定します
    4. 第4引数にイベントハンドラーの第2引数へ渡すウィジェット指定します
  4. void toggle_title(GtkWidget *widget, gpointer window)
    toggle_title( )関数の第1引数にはチェックボタンが、第2引数にはウィンドウが 入ります。
  5. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))
    gtk_toggle_button_get_active( )関数は 引数で指定したウィジェットの状態を取得します。 引数はGTK_TOGGLE_BUTTON( )マクロで囲む必要があります。


スケール

scale.c


#include <gtk/gtk.h>

void activate();
void value_changed();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.scale" ,     0   );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *hbox;
    GtkWidget   *scale;
    GtkWidget   *label;
    
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),    "Scale" );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    gtk_container_set_border_width  (GTK_CONTAINER(window), 15      );
    
    hbox    =   gtk_box_new         (GTK_ORIENTATION_HORIZONTAL, 0  );
    gtk_container_add               (GTK_CONTAINER(window),     hbox);
    
    scale   =
    gtk_scale_new_with_range        (GTK_ORIENTATION_HORIZONTAL,
                                     0,     100,    1           );
    gtk_scale_set_draw_value        (GTK_SCALE(scale), FALSE    );
    label   =   gtk_label_new       ("0");
    
    gtk_box_pack_start              (GTK_BOX(hbox), scale,  1, 1, 0 );
    gtk_box_pack_end                (GTK_BOX(hbox), label,  0, 0, 0 );
    
    g_signal_connect                (scale,     "value-changed",
                                     G_CALLBACK( value_changed),
                                     label);
    
    gtk_widget_show_all             (window);
}

void value_changed(GtkRange *range, gpointer label)
{
    gdouble val     =   gtk_range_get_value(   range);
    gchar   *str    =   g_strdup_printf("%.f", val  );
    gtk_label_set_text  (label, str);
    g_free(str);
}
    

実行結果


スライダーを動かすと、その値がラベルに表示されます。
ラベルに表示される文字列は、ユーザーが変更することはできませんが プログラム内部からは変更することができます。

コード説明

  1. scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 100, 1);
    gtk_scale_new_with_range( )関数でスケールを作ります。引数は次のとおりです。
    1. 第1引数にスケールの向きを定数で指定します
      GTK_ORIENTATION_HORIZONTAL横向き値は0
      GTK_ORIENTATION_VERTICAL縦向き値は1
    2. 第2引数にスケールの最小値を指定します
    3. 第3引数にスケールの最大値を指定します
    4. 第4引数にスケールの刻み幅を指定します
  2. gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
    スケールはデフォルトでスライドした位置に現在値が表示される仕組みになっています。
    今回は別の場所に現在値を表示したいので gtk_set_draw_value( )関数で現在値が スライドした位置に表示されない設定にします。
    引数は次のとおりです
    1. 第1引数にGTK_SCALE( )マクロで囲んでスケールを指定します
    2. 第2引数にTRUEかFALSEを指定します。 FALSEを指定するとスライドされた位置に現在値は表示されません
  3. g_signal_connect(scale, "value-changed", G_CALLBACK( value_changed), label);
    スケールの値が変更された時に発生するイベントは、"value-changed"です。
  4. void value_changed(GtkRange *range, gpointer label)
    スケールをGtkRange型のポインターとして受け取っています。
  5. gdouble val = gtk_range_get_value(range);
  6. gtk_range_get_value( )関数で引数rangeの現在値を取得できます。 取得した値をgdoubleというGTKで再定義されてたdouble型で受け取っていますが double、float、intで受け取っても問題ないみたいです。
  7. gchar *str = g_strdup_printf("%.f", val);
    g_strdup_printf( )関数は、変換指定子で変換された文字列を作ります。 今回の場合はval浮動小数点数を文字列に変換した新しい文字列が作られています。
  8. gtk_label_set_text(label, str);
    gtk_label_set_text( )関数は、第1引数のラベルに、第2引数の文字列を設定します。
  9. g_free(str);
    Cでは、関数が終了する時に内部の変数は破棄され 変数が使用していたメモリーが解放されます。しかしポインターの場合は ポインターは破棄されますが、そのポインターが指し示していたアドレスの値は 破棄されません。g_free関数を使うと、引数で指定したポインターが指し示す アドレスの値のメモリー領域を解放できます。


トグルボタン

togglebutton.c


#include <gtk/gtk.h>

guchar  r = 0;
guchar  g = 0;
guchar  b = 0;

void    activate        ();
void    draw_callback   ();
void    togglered       ();
void    togglegreen     ();
void    toggleblue      ();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.togglebutton", 0 );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *fixed;
    GtkWidget   *red;
    GtkWidget   *green;
    GtkWidget   *blue;
    GtkWidget   *darea;
    
    /*  Window          */
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),
                                     "ToggleButton"                 );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    
    /*  Fixed           */
    fixed   =   gtk_fixed_new       ();
    gtk_container_add               (GTK_CONTAINER(window), fixed   );
    
    /*  Buttons         */
    red     =
    gtk_toggle_button_new_with_label("Red");
    green   =
    gtk_toggle_button_new_with_label("Green");
    blue    =
    gtk_toggle_button_new_with_label("Blue");
    darea   =
    gtk_drawing_area_new            ();
    gtk_widget_set_size_request     (red,   100,    25);
    gtk_widget_set_size_request     (green, 100,    25);
    gtk_widget_set_size_request     (blue,  100,    25);
    gtk_widget_set_size_request     (darea, 110,   110);
    
    /*  Puts to fixed   */
    gtk_fixed_put                   (GTK_FIXED(fixed), red  , 20,  20);
    gtk_fixed_put                   (GTK_FIXED(fixed), green, 20,  70);
    gtk_fixed_put                   (GTK_FIXED(fixed), blue , 20, 120);
    gtk_fixed_put                   (GTK_FIXED(fixed), darea,150,  20);
    
    /*  Events          */
    g_signal_connect                (darea,     "draw",
                                     G_CALLBACK(draw_callback), NULL);
    g_signal_connect                (red,       "toggled",
                                     G_CALLBACK(togglered),   darea );
    g_signal_connect                (green,     "toggled",
                                     G_CALLBACK(togglegreen), darea );
    g_signal_connect                (blue,      "toggled",
                                     G_CALLBACK(toggleblue),  darea );
    
    gtk_widget_show_all             (window);
}

void draw_callback(GtkWidget *darea, cairo_t *cr)
{
    GdkRGBA     color;
    gchar       *rgb;
    
    rgb     =   g_strdup_printf     ("rgb(%d,%d,%d)", r, g, b);
    gdk_rgba_parse                  (&color, rgb);
    g_free                          (rgb);
    gdk_cairo_set_source_rgba       (cr, &color);
    cairo_paint                     (cr);
}

void togglered(GtkToggleButton *red, GtkWidget *darea)
{
    if (gtk_toggle_button_get_active(red))
        r   = 255;
    else
        r   =   0;
    gtk_widget_queue_draw(darea);
}

void togglegreen(GtkToggleButton *green, GtkWidget *darea)
{
    if (gtk_toggle_button_get_active(green))
        g   = 255;
    else
        g   =   0;
    gtk_widget_queue_draw(darea);
}

void toggleblue(GtkToggleButton *blue, GtkWidget *darea)
{
    if (gtk_toggle_button_get_active(blue))
        b   = 255;
    else
        b   =   0;
    gtk_widget_queue_draw(darea);
}
	


コード説明

  1. guchar r = 0;
    gucharは、GTKで再定義されたunsigned charです。 色の値が0から255なのでちょうど良い型です。
  2. gtk_toggle_button_new_with_label( )関数でトグルボタンを作ります。 引数にトグルボタンに表示される文字列を指定します。
  3. gtk_drawing_area_new( )関数でドローイングエリアを作ります。 引数はありません。ドローイングエリアは様々なグラフィックスを描く土台になります。
  4. g_signal_connect(darea, "draw", G_CALLBACK(draw_callback), NULL);
    ドローイングアリアが再描画される時のイベントは "draw" です。
  5. g_signal_connect(red, "toggled", G_CALLBACK(togglered), darea );
    トグルボタンが押された時のイベントは "toggled" です。
  6. void draw_callback(GtkWidget *darea, cairo_t *cr)
    ドローイングエリアでイベントが発生した時は、カイロ(cairo)が cairo_t 型として イベントハンドラーの第2引数へ自動的に渡されます。
    カイロは描画を行うシステムです。 ドローイングエリアはグラフィックスを描画するための土台です。 カイロがドローイングエリアへ描画します。
  7. GdkRGBA color;
    GTKでカラーを保持する型はGdkRGBAです。
  8. gchar *rgb;
    ghar*はGTKで再定義されたchar *です。
  9. g_strdup_printf( )関数は書式指定した文字列を作ります。
  10. gdk_rgba_parse( )関数は、第1引数のカラー変数に、 第2引数の文字列から分析(parse)した色を入れます。
  11. g_free関数は、引数のポインターが指し示すアドレスのメモリー領域を解放します。 rgbはポインターなので解放しておきます。
  12. gdk_cairo_set_source_rgba( )関数は、 第1引数のカイロに、第2引数の色を設定します。
  13. cairo_paint( )関数は、引数で指定したカイロを現在の色を塗りつぶします。
  14. void togglered(GtkToggleButton *red, GtkWidget *darea)
    トグルボタンのイベントハンドラーが受け取る第1引数の型は GTKToggleButtonにした方が良いみたいです。
  15. gtk_toggle_button_get_active( )関数は引数のトグルボタンが 押された状態がどうかを取得します。押されていればTRUEが返されます。
  16. gtk_widget_queue_draw( )関数は、引数のウィジェットを再描画します。
    ドローイングエリアの "draw" イベントは ドローイングエリアが再描画される時に発生します。


ラジオボタン

radiobutton.c


#include <gtk/gtk.h>

void    activate    ();
void    on_toggle   ();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.radiobutton", 0  );
    g_signal_connect                (app,   "activate",
                                     G_CALLBACK(activate),  NULL    );
    status  =   g_application_run   (G_APPLICATION(app), argc, argv );
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *frame;
    GtkWidget   *vbox;
    GtkWidget   *hbox;
    GtkWidget   *red;
    GtkWidget   *green;
    GtkWidget   *blue;
    GSList      *group = NULL;
    
    /*  Window          */
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),
                                     "RadioButton"    );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    gtk_container_set_border_width  (GTK_CONTAINER(window), 15      );
    
    /*  Containers      */
    frame   =   gtk_frame_new       ("Red");
    vbox    =   gtk_box_new         (GTK_ORIENTATION_VERTICAL,   0  );
    hbox    =   gtk_box_new         (GTK_ORIENTATION_HORIZONTAL, 0  );
    gtk_container_add               (GTK_CONTAINER(window), frame   );
    gtk_container_add               (GTK_CONTAINER(frame ), vbox    );
    gtk_box_pack_start              (GTK_BOX(vbox), hbox,   1, 0, 0 );
    
    /*  Radio buttons   */
    red     =
    gtk_radio_button_new_with_label (group,                 "Red"   );
    green   =
    gtk_radio_button_new_with_label_from_widget
                                    (GTK_RADIO_BUTTON(red), "Green" );
    blue    =
    gtk_radio_button_new_with_label_from_widget
                                    (GTK_RADIO_BUTTON(red), "Blue"  );
    
    /*  Pack to box     */
    gtk_box_pack_start              (GTK_BOX(hbox), red  ,  1, 0, 0 );
    gtk_box_pack_start              (GTK_BOX(hbox), green,  1, 0, 0 );
    gtk_box_pack_end                (GTK_BOX(hbox), blue ,  1, 0, 0 );
    
    /*  Signals         */
    g_signal_connect                (red,   "toggled",
                                     G_CALLBACK(on_toggle), frame   );
    g_signal_connect                (green, "toggled",
                                     G_CALLBACK(on_toggle), frame   );
    g_signal_connect                (blue,  "toggled",
                                     G_CALLBACK(on_toggle), frame   );
    
    gtk_widget_show_all             (window);
}

void on_toggle(GtkButton *button, GtkFrame *frame)
{
    const gchar *label = gtk_button_get_label(button);
    gtk_frame_set_label(frame, label);
}
	

実行結果


ラジオボタンをクリックすると、そのラベルが、フレームのラベルになります。

macOSの場合、チェックボタンとラジオボタンを使った場合に、 実行時に次のような警告が出ることがありますが、結果には影響ありません。


(a.out:736): Gtk-WARNING **: 07:33:22.044: Could not load a pixbuf
from /org/gtk/libgtk/theme/Adwaita/assets/bullet-symbolic.svg.
This may indicate that pixbuf loaders or the mime database could not be
found.
    

コード説明

  1. GSList *group = NULL;
    ボタンのグループを登録するためにGSList型のポインターが必要になります。 NULLで初期化しておいたほうが良いみたいです。
    グループに登録されたラジオボタンは、そのグループから一つだけが 選択できるようになります。
  2. frame = gtk_frame_new ("Red");
    フレームを作っています。 引数に文字列を渡すと、その文字列がフレームのラベルとして表示されます。 ラベルが不要な場合には NULL を渡します。
  3. red = gtk_radio_button_new_with_label(group, "Red");
    ラジオボタンを作っています。第1引数にグループを、 第2引数にラベルに表示される文字列を指定します。
  4. gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(red), "Green");
    同じくラジオボタンを作っていますが、今度は 第1引数にグループに登録ずみのラジオボタンを指定します。 こうすることで、同じグループのラジオボタンになります。
    ラジオボタンをグループに追加する方法はいくつかありますが、 今回の方法が、コンパイル時に一番警告(warning)が出ない方法でした。
  5. g_signal_connect(red, "toggled", G_CALLBACK(on_toggle),frame);
    ラジオボタンが選ればれた時のイベントは "toggled" です。 第4引数はNULLではなく、frameを渡しています。 こうすることでイベントハンドラーの第2引数にframeが渡されます。
  6. void on_toggle(GtkButton *button, GtkFrame *frame)
    今回、イベントハンドラーでは、ラジオボタンをGtkButton型で、 フレームをGtkFrame型で受けることにしました。
  7. const gchar * label = gtk_button_get_label(button);
    ボタンのラベルを取得しています。この関数は const gchar *型の文字列を返します。
    引数は GTkButton 型でなければコンパイル時に警告が出ます。 そのため、イベントハンドラーの定義でGtkButton型にしました。
  8. gtk_frame_set_label(frame, label);
    この関数で、第1引数のフレームのラベルを、第2引数の文字列で設定します。 ここでも第1引数は GtkFrame 型でなければコンパイル時に警告が出ます。
    そのため、イベントハンドラーの定義で、第2引数をGtkFrame 型にしました。


コンボボックステキスト

comboboxtext.c


#include <gtk/gtk.h>

void    activate        ();
void    select_combo    ();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.comboboxtext", 0 );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *vbox;
    GtkWidget   *combo;
    GtkWidget   *label;
    
    /*  Window          */
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window),
                                     "ComboBoxText"   );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    gtk_container_set_border_width  (GTK_CONTAINER(window), 15      );
    
    /*  Container       */
    vbox    =   gtk_box_new         (GTK_ORIENTATION_VERTICAL,  0   );
    gtk_container_add               (GTK_CONTAINER(window), vbox    );
    
    /*  ComboBoxText    */
    combo   =
    gtk_combo_box_text_new          ();
    gtk_combo_box_text_append       (GTK_COMBO_BOX_TEXT(combo), NULL,
                                     "Windows"  );
    gtk_combo_box_text_append       (GTK_COMBO_BOX_TEXT(combo), NULL,
                                     "macOS"    );
    gtk_combo_box_text_append       (GTK_COMBO_BOX_TEXT(combo), NULL,
                                     "Ubuntu"   );
    gtk_combo_box_text_append       (GTK_COMBO_BOX_TEXT(combo), NULL,
                                     "Fedora"   );
    
    /*  Label           */
    label   =   gtk_label_new       ("Unselected");
    
    /*  Pack to box     */
    gtk_box_pack_start              (GTK_BOX(vbox), combo,  0, 0, 0 );
    gtk_box_pack_end                (GTK_BOX(vbox), label,  1, 0, 0 );
    
    /*  Signal          */
    g_signal_connect                (combo, "changed",
                                     G_CALLBACK(select_combo), label);
    
    gtk_widget_show_all             (window);
}

void select_combo(GtkComboBoxText *combo, GtkLabel *label)
{
    gchar *os;
    os = gtk_combo_box_text_get_active_text(combo);
    gtk_label_set_text(label, os);
}
	

実行結果

コンボボックステキストで項目を選択すると、 選択された項目の文字列がラベルに表示されます。

コード説明

  1. gtk_combo_box_text_new( )関数でコンボボックステキストを作ります。 引数はありません。
  2. gtk_combo_box_text_append( ) 関数でコンボボックステキストに項目を追加します。引数は次のとおりです。
    1. 第1引数にGTK_COMBO_BOX_TEXT( ) マクロで囲んでコンボボックステキストを指定します
    2. 第2引数に項目のIDを整数で指定します。NULL と指定することもできます
    3. 第3引数に項目に表示される文字列を指定します
  3. g_signal_connect(combo, "changed", G_CALLBACK(select_combo), label);
    コンボボックステキストの項目が選択された時に発生するイベントは "changed" です。
  4. void select_combo(GtkComboBoxText *combo, GtkLabel *label)
    イベントハンドラーでは、コンボボックステキストをGtkComboBoxText型、 ラベルをGtkLabel型で受けています。
  5. gtk_combo_box_text_get_active_text( )関数は、 引数で指定したコンボボックステキストで現在選択されている項目の文字列を gchar *型で返します。
    イベントハンドラーで combo を GtkWidget 型で受けていた場合は、 GTK_COMBO_BOX_TEXT(combo)とキャストしなければコンパイル時に警告が出ます。
  6. gtk_label_set_text( )関数は、第1引数のラベルに、第2引数の gchar *型の文字列を設定します。
    イベントハンドラーで label を GtkWidget 型で受けていた場合は、 GTK_LABEL(label)とキャストしなければコンパイル時に警告が出ます。


リストボックス

listbox.c


#include <gtk/gtk.h>

void    activate    ();
void    select_list ();

int main(int argc, char **argv)
{
    GtkApplication  *app;
    int             status;
    
    app     =   gtk_application_new ("jp.vivacocoa.listbox",    0   );
    g_signal_connect                (app,       "activate",
                                     G_CALLBACK( activate),     NULL);
    status  =   g_application_run   (G_APPLICATION(app), argc,  argv);
    g_object_unref                  (app);
    return      status;
}

void activate(GtkApplication *app, gpointer data)
{
    GtkWidget   *window;
    GtkWidget   *vbox;
    GtkWidget   *listbox;
    GtkWidget   *label;
    
    /*  Window          */
    window  =
    gtk_application_window_new      (app);
    gtk_window_set_title            (GTK_WINDOW(window), "ListBox"  );
    gtk_window_set_default_size     (GTK_WINDOW(window),    300, 200);
    gtk_window_set_position         (GTK_WINDOW(window),    1       );
    gtk_container_set_border_width  (GTK_CONTAINER(window), 15      );
    
    /*  Container       */
    vbox    =   gtk_box_new         (GTK_ORIENTATION_VERTICAL,  15  );
    gtk_container_add               (GTK_CONTAINER(window),     vbox);
    
    /*  ListBox         */
    listbox =   gtk_list_box_new    ();
    gtk_list_box_insert             (GTK_LIST_BOX(listbox),
                                     gtk_label_new("Windows"),  -1  );
    gtk_list_box_insert             (GTK_LIST_BOX(listbox),
                                     gtk_label_new("macOS"  ),  -1  );
    gtk_list_box_insert             (GTK_LIST_BOX(listbox),
                                     gtk_label_new("Ubuntu" ),  -1  );
    gtk_list_box_insert             (GTK_LIST_BOX(listbox),
                                     gtk_label_new("Fedora" ),  -1  );
    
    /*  Label           */
    label   =   gtk_label_new       (NULL);
    
    /*  Pack to box     */
    gtk_box_pack_start              (GTK_BOX(vbox), listbox, 1, 1, 0);
    gtk_box_pack_end                (GTK_BOX(vbox), label,   0, 0, 0);
    
    /*  Signal          */
    g_signal_connect                (listbox,   "row_selected",
                                     G_CALLBACK(select_list),   label);
    
    gtk_widget_show_all             (window);
}

void select_list(GtkListBox *list, GtkListBoxRow *row, GtkLabel *label)
{
    GtkWidget *child = gtk_bin_get_child(GTK_BIN(row));
    gtk_label_set_text(label, gtk_label_get_text(GTK_LABEL(child)));
}
	

実行結果


リストボックスで項目を選択すると、 選択された項目の文字列がラベルに表示されます。

コード説明

  1. listbox = gtk_list_box_new();
    gtk_list_box_new( )関数でリストボックスを作ります。引数はありません。
  2. gtk_list_box_insert(GTK_LIST_BOX(listbox), gtk_label_new("Windows"), -1);
    gkt_list_box_insert( )関数で リストボックスの指定位置にウィジェットを挿入します。引数は次のとおりです。
    1. 第1引数にGTK_LIST_BOX( )マクロで囲んでリストボックスを指定します
    2. 第2引数にリストに挿入するウィジェットを指定します。
    3. 第3引数に挿入する位置を指定します。 -1 を指定するとリストの最後を指定したことになります。
  3. gtk_label_new(NULL)
    引数に NULL を渡してラベルを作ることもできます。
  4. g_signal_connect(listbox, "row_selected", G_CALLBACK(select_list), label);
    リストボックスで項目を選択した時のイベントは "row_selected" です。 "row_activated" イベントも使えます。 イベントハンドラーに引数としてラベルを渡しています。
  5. void select_list(GtkListBox *list, GtkListBoxRow * row, GtkLabel *label)

    リストボックスを "row_selected" で接続したイベントハンドラーには、 自動的に、リストボックスと選択されたリストボックスの行が渡されます。
  6. GtkWidget *child = gtk_bin_get_child(GTK_BIN(row));
    gtk_bin_get_child(GTK_BIN(row))で リストボックスの行に設定されたウィジェットが取得できます。
  7. gtk_label_set_text(label, gtk_label_get_text(GTK_LABEL(child)));
    上記で取得したウィジェットを、GTK_LABEL( )マクロでラベルにキャストして、 gtk_label_get_text( )関数に渡しています。



2088 visits
Posted: Jan. 06, 2020
Update: Jan. 07, 2020

ホーム   C/C++チュートリアル   目次