原文: http://zetcode.com/gui/gtk2/gtkwidgets/

在 GTK+ 编程教程的这一部分中,我们将介绍一些 GTK+ 小部件。

小部件是 GUI 应用的基本构建块。 多年来,一些小部件已成为编程工具包的标准。 例如按钮,复选框或滚动条。 GTK+ 工具箱的理念是将小部件的数量保持在最低水平。 将创建更多专门的小部件作为定制 GTK+ 小部件。

GtkButton

GtkButton是用于触发动作的简单小部件。

button.c

  1. #include <gtk/gtk.h>
  2. int main(int argc, char *argv[]) {
  3. GtkWidget *window;
  4. GtkWidget *halign;
  5. GtkWidget *btn;
  6. gtk_init(&argc, &argv);
  7. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  8. gtk_window_set_title(GTK_WINDOW(window), "GtkButton");
  9. gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
  10. gtk_container_set_border_width(GTK_CONTAINER(window), 15);
  11. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  12. halign = gtk_alignment_new(0, 0, 0, 0);
  13. gtk_container_add(GTK_CONTAINER(window), halign);
  14. btn = gtk_button_new_with_label("Quit");
  15. gtk_widget_set_size_request(btn, 70, 30);
  16. gtk_container_add(GTK_CONTAINER(halign), btn);
  17. g_signal_connect(G_OBJECT(btn), "clicked",
  18. G_CALLBACK(gtk_main_quit), G_OBJECT(window));
  19. g_signal_connect(G_OBJECT(window), "destroy",
  20. G_CALLBACK(gtk_main_quit), NULL);
  21. gtk_widget_show_all(window);
  22. gtk_main();
  23. return 0;
  24. }

该示例显示了一个位于窗口左上角的按钮。 当我们单击按钮时,应用退出。

  1. btn = gtk_button_new_with_label("Quit");

gtk_button_new_with_label()创建一个带有标签的新GtkButton

  1. g_signal_connect(G_OBJECT(btn), "clicked",
  2. G_CALLBACK(gtk_main_quit), G_OBJECT(window));

按钮的clicked信号连接到gtk_main_quit()函数,该功能终止应用。

GTK  小部件 - 图1

图:GtkButton

GtkCheckButton

GtkCheckButton是具有两种状态的窗口小部件:打开和关闭。 接通状态通过复选标记显示。

checkbutton.c

  1. #include <gtk/gtk.h>
  2. void toggle_title(GtkWidget *widget, gpointer window) {
  3. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
  4. gtk_window_set_title(window, "GtkCheckButton");
  5. } else {
  6. gtk_window_set_title(window, "");
  7. }
  8. }
  9. int main(int argc, char** argv) {
  10. GtkWidget *window;
  11. GtkWidget *halign;
  12. GtkWidget *cb;
  13. gtk_init(&argc, &argv);
  14. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  15. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  16. gtk_container_set_border_width(GTK_CONTAINER(window), 15);
  17. gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
  18. gtk_window_set_title(GTK_WINDOW(window), "GtkCheckButton");
  19. halign = gtk_alignment_new(0, 0, 0, 0);
  20. gtk_container_add(GTK_CONTAINER(window), halign);
  21. cb = gtk_check_button_new_with_label("Show title");
  22. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), TRUE);
  23. GTK_WIDGET_UNSET_FLAGS(cb, GTK_CAN_FOCUS);
  24. gtk_container_add(GTK_CONTAINER(halign), cb);
  25. g_signal_connect(window, "destroy",
  26. G_CALLBACK(gtk_main_quit), NULL);
  27. g_signal_connect(cb, "clicked",
  28. G_CALLBACK(toggle_title), (gpointer) window);
  29. gtk_widget_show_all(window);
  30. gtk_main();
  31. return 0;
  32. }

该示例根据GtkCheckButton的状态显示窗口标题。

  1. cb = gtk_check_button_new_with_label("Show title");
  2. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), TRUE);

GtkCheckButton已创建并默认标记。 标题最初显示。

  1. GTK_WIDGET_UNSET_FLAGS(cb, GTK_CAN_FOCUS);

此代码行禁用焦点。

  1. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
  2. gtk_window_set_title(window, "GtkCheckButton");
  3. } else {
  4. gtk_window_set_title(window, "");
  5. }

我们根据GtkCheckButton的状态显示窗口的标题。 要设置窗口的标题,我们使用gtk_window_set_title()

GTK  小部件 - 图2

图:GtkCheckButton

GtkFrame

GtkFrame是一个带有装饰框和可选标签的垃圾桶。

frames.c

  1. #include <gtk/gtk.h>
  2. int main(int argc, char *argv[]) {
  3. GtkWidget *window;
  4. GtkWidget *table;
  5. GtkWidget *frame1;
  6. GtkWidget *frame2;
  7. GtkWidget *frame3;
  8. GtkWidget *frame4;
  9. gtk_init(&argc, &argv);
  10. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  11. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  12. gtk_window_set_default_size(GTK_WINDOW(window), 250, 250);
  13. gtk_window_set_title(GTK_WINDOW(window), "GtkFrame");
  14. gtk_container_set_border_width(GTK_CONTAINER(window), 10);
  15. table = gtk_table_new(2, 2, TRUE);
  16. gtk_table_set_row_spacings(GTK_TABLE(table), 10);
  17. gtk_table_set_col_spacings(GTK_TABLE(table), 10);
  18. gtk_container_add(GTK_CONTAINER(window), table);
  19. frame1 = gtk_frame_new("Shadow In");
  20. gtk_frame_set_shadow_type(GTK_FRAME(frame1), GTK_SHADOW_IN);
  21. frame2 = gtk_frame_new("Shadow Out");
  22. gtk_frame_set_shadow_type(GTK_FRAME(frame2), GTK_SHADOW_OUT);
  23. frame3 = gtk_frame_new("Shadow Etched In");
  24. gtk_frame_set_shadow_type(GTK_FRAME(frame3), GTK_SHADOW_ETCHED_IN);
  25. frame4 = gtk_frame_new("Shadow Etched Out");
  26. gtk_frame_set_shadow_type(GTK_FRAME(frame4), GTK_SHADOW_ETCHED_OUT);
  27. gtk_table_attach_defaults(GTK_TABLE(table), frame1, 0, 1, 0, 1);
  28. gtk_table_attach_defaults(GTK_TABLE(table), frame2, 0, 1, 1, 2);
  29. gtk_table_attach_defaults(GTK_TABLE(table), frame3, 1, 2, 0, 1);
  30. gtk_table_attach_defaults(GTK_TABLE(table), frame4, 1, 2, 1, 2);
  31. g_signal_connect(G_OBJECT(window), "destroy",
  32. G_CALLBACK(gtk_main_quit), G_OBJECT(window));
  33. gtk_widget_show_all(window);
  34. gtk_main();
  35. return 0;
  36. }

该示例显示了四种不同的帧类型。 框架连接到表格容器中。

  1. frame1 = gtk_frame_new("Shadow In");

gtk_frame_new()函数创建带有可选标签的GtkFrame

  1. gtk_frame_set_shadow_type(GTK_FRAME(frame1), GTK_SHADOW_IN);

gtk_frame_set_shadow_type()函数设置帧的阴影类型。

GTK  小部件 - 图3

图:GtkFrame

GtkHScale

GtkHScale是用于从一系列值中选择一个值的水平滑块控件。

hscale.c

  1. void value_changed(GtkRange *range, gpointer win) {
  2. gdouble val = gtk_range_get_value(range);
  3. gchar *str = g_strdup_printf("%.f", val);
  4. gtk_label_set_text(GTK_LABEL(win), str);
  5. g_free(str);
  6. }
  7. int main(int argc, char *argv[]) {
  8. GtkWidget *window;
  9. GtkWidget *halign;
  10. GtkWidget *hbox;
  11. GtkWidget *hscale;
  12. GtkWidget *label;
  13. gtk_init(&argc, &argv);
  14. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  15. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  16. gtk_window_set_default_size(GTK_WINDOW(window), 300, 250);
  17. gtk_container_set_border_width(GTK_CONTAINER(window), 10);
  18. gtk_window_set_title(GTK_WINDOW(window), "GtkHScale");
  19. hbox = gtk_hbox_new(FALSE, 20);
  20. hscale = gtk_hscale_new_with_range(0, 100, 1);
  21. gtk_scale_set_draw_value(GTK_SCALE(hscale), FALSE);
  22. gtk_widget_set_size_request(hscale, 150, -1);
  23. label = gtk_label_new("...");
  24. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 1);
  25. gtk_box_pack_start(GTK_BOX(hbox), hscale, FALSE, FALSE, 0);
  26. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
  27. halign = gtk_alignment_new(0, 0, 0, 0);
  28. gtk_container_add(GTK_CONTAINER(halign), hbox);
  29. gtk_container_add(GTK_CONTAINER(window), halign);
  30. g_signal_connect(window, "destroy",
  31. G_CALLBACK(gtk_main_quit), NULL);
  32. g_signal_connect(hscale, "value-changed",
  33. G_CALLBACK(value_changed), label);
  34. gtk_widget_show_all(window);
  35. gtk_main();
  36. return 0;
  37. }

在示例中,我们有一个水平比例小部件和一个标签小部件。 当前选择的值显示在标签中。

  1. gdouble val = gtk_range_get_value(range);

gtk_range_get_value()函数从比例小部件中检索当前选择的值。

  1. gchar *str = g_strdup_printf("%.f", val);
  2. gtk_label_set_text(GTK_LABEL(win), str);

我们使用g_strdup_printf()函数构建一个字符串值,并使用gtk_label_set_text()函数将其设置为标签。

  1. hscale = gtk_hscale_new_with_range(0, 100, 1);

gtk_hscale_new_with_range()函数创建一个具有给定范围的新水平比例小部件。 第一个参数是最小值,第二个参数是最大值,最后一个参数是步骤。

  1. gtk_scale_set_draw_value(GTK_SCALE(hscale), FALSE);

gtk_scale_set_draw_value()指定当前值是否在字符串旁边显示为字符串。 我们关闭该值。 相反,我们以编程方式将其设置为标签小部件。

GTK  小部件 - 图4

图:GtkHScale

GtkLabel

GtkLabel小部件显示文本。

label.c

  1. #include <gtk/gtk.h>
  2. int main(int argc, char *argv[]) {
  3. GtkWidget *window;
  4. GtkWidget *label;
  5. gtk_init(&argc, &argv);
  6. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  7. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  8. gtk_window_set_title(GTK_WINDOW(window), "No sleep");
  9. gtk_container_set_border_width(GTK_CONTAINER(window), 15);
  10. label = gtk_label_new("I've always been too lame\n\
  11. To see what's before me\n\
  12. And I know nothing sweeter than\n\
  13. Champaign from last New Years\n\
  14. Sweet music in my ears\n\
  15. And a night full of no fears\n\
  16. \n\
  17. But if I had one wish fulfilled tonight\n\
  18. I'd ask for the sun to never rise\n\
  19. If God passed a mic to me to speak\n\
  20. I'd say \"Stay in bed, world,\n\
  21. Sleep in peace");
  22. gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
  23. gtk_container_add(GTK_CONTAINER(window), label);
  24. g_signal_connect(window, "destroy",
  25. G_CALLBACK(gtk_main_quit), NULL);
  26. gtk_widget_show_all(window);
  27. gtk_main();
  28. return 0;
  29. }

该示例显示了歌曲的两节经文。

  1. label = gtk_label_new("I've always been too lame\n\
  2. To see what's before me\n\
  3. ...

我们创建一个GtkLabel小部件。 我们可以使用换行符来创建多行文本标签。 注意转义符。 我们使用了相当长的字符串,并且我们不想将所有文本都放在一行中。 在这种情况下,我们可以使用转义符。

  1. gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);

gtk_label_set_justify()函数使标签中的文本对齐。 使用GTK_JUSTIFY_CENTER类型时,文本居中。

GTK  小部件 - 图5

图:GtkLabel

GtkLabel

GtkLabel也可以显示标记语言。 标记是 Pango 文本标记语言。

markup.c

  1. #include <gtk/gtk.h>
  2. int main(int argc, char *argv[]) {
  3. GtkWidget *window;
  4. GtkWidget *label;
  5. gtk_init(&argc, &argv);
  6. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  7. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  8. gtk_window_set_default_size(GTK_WINDOW(window), 300, 100);
  9. gtk_window_set_title(GTK_WINDOW(window), "Markup label");
  10. gchar *str = "<b>ZetCode</b>, knowledge only matters";
  11. label = gtk_label_new(NULL);
  12. gtk_label_set_markup(GTK_LABEL(label), str);
  13. gtk_container_add(GTK_CONTAINER(window), label);
  14. gtk_widget_show(label);
  15. g_signal_connect(window, "destroy",
  16. G_CALLBACK(gtk_main_quit), NULL);
  17. gtk_widget_show(window);
  18. gtk_main();
  19. return 0;
  20. }

该示例以粗体显示了一部分文本。

  1. gchar *str = "<b>ZetCode</b>, knowledge only matters";

这是显示的字符串。 它包含一个简单的标记。

  1. label = gtk_label_new(NULL);

我们创建一个空标签。

  1. gtk_label_set_markup(GTK_LABEL(label), str);

gtk_label_set_markup()解析标记的字符串,并将其属性应用于标签。

GTK  小部件 - 图6

图:标记标签

在 GTK+ 教程的这一部分中,我们介绍了 GTK+ 小部件。