有些动作action有状态。状态的典型值是布尔值或字符串。但是,如果你愿意,也可以使用其他类型的状态。
具有状态的动作称为有状态的。
有些菜单被称为切换菜单。例如,全屏菜单有一个状态,它有两个值——全屏和非全屏。每次单击菜单时,状态的值都会改变。一个动作对应全屏菜单也有一个状态。它的值为TRUE或FALSE,称为布尔值。TRUE表示全屏,FALSE表示非全屏。
下面是除信号处理程序之外实现全屏菜单的示例代码。稍后将介绍信号处理程序。
GSimpleAction *act_fullscreen = g_simple_action_new_stateful ("fullscreen",
NULL, g_variant_new_boolean (FALSE));
g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_fullscreen));
... ... ...
GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen");
1 static void
2 fullscreen_changed(GSimpleAction *action, GVariant *value, GtkWindow *win) {
3 if (g_variant_get_boolean (value))
4 gtk_window_maximize (win);
5 else
6 gtk_window_unmaximize (win);
7 g_simple_action_set_state (action, value);
8 }
你可以使用“activate”信号代替“change-state”信号,或者同时使用两种信号。但上面的方法是最简单也是最好的。
GVarient可以包含布尔值、字符串或其他类型的值。例如,下面的程序将TRUE赋值给类型为GVariant的值。
GVariant *value = g_variant_new_boolean (TRUE);
另一个例子是:
GVariant *value2 = g_variant_new_string ("Hello");
value2是一个GVariant,它的值是字符串类型"Hello"。GVariant可以包含其他类型,如int16、int32、int64、double等。
如果你想获得原始值,可以使用g_variant_get系列函数。例如,可以使用g_variant_get_boolean获取布尔值。
gboolean bool = g_variant_get_boolean (value);
因为value被创建为布尔类型GVariant和TRUE value,所以bool等于TRUE。同样,你可以从value2中得到一个字符串
const char *str = g_variant_get_string (value2, NULL);
第二个形参是一个指向gsize类型变量的指针(gsize定义为unsigned long)。如果它不是NULL,那么字符串的长度将由函数设置。如果是NULL,什么都不会发生。返回的字符串str不能更改。
另一个有状态操作的例子是与颜色选择菜单相对应的操作。例如,有三个菜单,每个菜单分别有红色、绿色和蓝色。它们确定GtkLabel部件的背景颜色。一个操作连接到三个菜单。这个动作有一个值为"red"、"green"或"blue"的状态。值是字符串。这些颜色作为参数提供给信号处理程序。
... ... ...
GSimpleAction *act_color = g_simple_action_new_stateful ("color",
g_variant_type_new("s"), g_variant_new_string ("red"));
GMenuItem *menu_item_red = g_menu_item_new ("Red", "app.color::red");
GMenuItem *menu_item_green = g_menu_item_new ("Green", "app.color::green");
GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "app.color::blue");
g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), NULL);
... ... ...
下面是“activate”信号处理程序。
static void
color_activated(GSimpleAction *action, GVariant *parameter) {
char *color = g_strdup_printf ("label.lb {background-color: %s;}",
g_variant_get_string (parameter, NULL));
gtk_css_provider_load_from_data (provider, color, -1);
g_free (color);
g_action_change_state (G_ACTION (action), parameter);
}
注意:如果您没有设置“activate”信号处理程序,信号将被转发到“change-state”信号。因此,你可以使用“change-state”信号而不是“activate”信号。看src/menu/menu2_change_state.c.
GVariantType给出GVariant的类型。GVariant可以包含多种类型。而且类型通常需要在运行时识别。
GVariantType由一个表示类型的字符串创建。
“b”表示布尔类型。
“s”表示字符串类型。
下面的程序是一个简单的例子。最后输出字符串"s"。
1 #include <glib.h>
2
3 int
4 main (int argc, char **argv) {
5 GVariantType *vtype = g_variant_type_new ("s");
6 const char *type_string = g_variant_type_peek_string (vtype);
7 g_print ("%s\n",type_string);
8 }
下面的代码包含了上面的有状态操作。这个程序有这样的菜单:

代码如下。
1 #include <gtk/gtk.h>
2
3 /* The provider below provides application wide CSS data. */
4 GtkCssProvider *provider;
5
6 static void
7 fullscreen_changed(GSimpleAction *action, GVariant *value, GtkWindow *win) {
8 if (g_variant_get_boolean (value))
9 gtk_window_maximize (win);
10 else
11 gtk_window_unmaximize (win);
12 g_simple_action_set_state (action, value);
13 }
14
15 static void
16 color_activated(GSimpleAction *action, GVariant *parameter) {
17 char *color = g_strdup_printf ("label.lb {background-color: %s;}", g_variant_get_string (parameter, NULL));
18 /* Change the CSS data in the provider. */
19 /* Previous data is thrown away. */
20 gtk_css_provider_load_from_data (provider, color, -1);
21 g_free (color);
22 g_action_change_state (G_ACTION (action), parameter);
23 }
24
25 static void
26 remove_provider (GApplication *app, GtkCssProvider *provider) {
27 GdkDisplay *display = gdk_display_get_default();
28
29 gtk_style_context_remove_provider_for_display (display, GTK_STYLE_PROVIDER (provider));
30 g_object_unref (provider);
31 }
32
33 static void
34 app_activate (GApplication *app) {
35 GtkWindow *win = GTK_WINDOW (gtk_application_window_new (GTK_APPLICATION (app)));
36 gtk_window_set_title (win, "menu2");
37 gtk_window_set_default_size (win, 400, 300);
38
39 GtkWidget *lb = gtk_label_new (NULL);
40 gtk_widget_add_css_class (lb, "lb"); /* the class is used by CSS Selector */
41 gtk_window_set_child (win, lb);
42
43 GSimpleAction *act_fullscreen
44 = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE));
45 g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
46 g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_fullscreen));
47
48 gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
49
50 gtk_window_present (win);
51 }
52
53 static void
54 app_startup (GApplication *app) {
55 GSimpleAction *act_color
56 = g_simple_action_new_stateful ("color", g_variant_type_new("s"), g_variant_new_string ("red"));
57 GSimpleAction *act_quit
58 = g_simple_action_new ("quit", NULL);
59 g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), NULL);
60 g_signal_connect_swapped (act_quit, "activate", G_CALLBACK (g_application_quit), app);
61 g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_color));
62 g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit));
63
64 GMenu *menubar = g_menu_new ();
65 GMenu *menu = g_menu_new ();
66 GMenu *section1 = g_menu_new ();
67 GMenu *section2 = g_menu_new ();
68 GMenu *section3 = g_menu_new ();
69 GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen");
70 GMenuItem *menu_item_red = g_menu_item_new ("Red", "app.color::red");
71 GMenuItem *menu_item_green = g_menu_item_new ("Green", "app.color::green");
72 GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "app.color::blue");
73 GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit");
74
75 g_menu_append_item (section1, menu_item_fullscreen);
76 g_menu_append_item (section2, menu_item_red);
77 g_menu_append_item (section2, menu_item_green);
78 g_menu_append_item (section2, menu_item_blue);
79 g_menu_append_item (section3, menu_item_quit);
80 g_object_unref (menu_item_red);
81 g_object_unref (menu_item_green);
82 g_object_unref (menu_item_blue);
83 g_object_unref (menu_item_fullscreen);
84 g_object_unref (menu_item_quit);
85
86 g_menu_append_section (menu, NULL, G_MENU_MODEL (section1));
87 g_menu_append_section (menu, "Color", G_MENU_MODEL (section2));
88 g_menu_append_section (menu, NULL, G_MENU_MODEL (section3));
89 g_menu_append_submenu (menubar, "Menu", G_MENU_MODEL (menu));
90
91 gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
92
93 provider = gtk_css_provider_new ();
94 /* Initialize the css data */
95 gtk_css_provider_load_from_data (provider, "label.lb {background-color: red;}", -1);
96 /* Add CSS to the default GdkDisplay. */
97 GdkDisplay *display = gdk_display_get_default ();
98 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider),
99 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
100 g_signal_connect (app, "shutdown", G_CALLBACK (remove_provider), provider);
101 }
102
103 #define APPLICATION_ID "com.github.ToshioCP.menu2"
104
105 int
106 main (int argc, char **argv) {
107 GtkApplication *app;
108 int stat;
109
110 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
111 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
112 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
113
114 stat =g_application_run (G_APPLICATION (app), argc, argv);
115 g_object_unref (app);
116 return stat;
117 }
118
将当前目录更改为src/menu。
$ comp menu2
$./a.out
然后,您将看到一个窗口,内容的背景色为红色。您可以将大小更改为最大,然后再更改为原始大小。您可以更改背景颜色为绿色或蓝色。
如果再次运行应用程序,同一个屏幕上会出现另一个窗口。两个窗口的背景颜色相同。因为act_color动作具有“app”作用域,并且CSS应用于由windows共享的默认显示。
我想从gtk3中的Widget发出自定义信号。在GTK2中,有一个名为signal_new的函数来创建一个新信号。您可以在此处查看示例:https://github.com/ruby-gnome2/ruby-gnome2/blob/ec373f87e672dbeeaa157f9148d18b34713bb90e/glib2/sample/type-register.rb在GTK3中,这个功能似乎不再可用。那么在ruby的GTK3中创建自定义信号的新方法是什么? 最佳答案 GTK3更改为使用define_signal方法而不是si
文章目录Kubernetes(k8s)工作负载一、Workloads二、Pod三、Deployment四、RC、RS、DaemonSet、StatefulSet五、Job、CronJob1、Job2、CronJob六、GCKubernetes(k8s)工作负载一、Workloads什么是工作负载(Workloads)工作负载是运行在Kubernetes上的一个应用程序。一个应用很复杂,可能由单个组件或者多个组件共同完成。无论怎样我们可以用一组Pod来表示一个应用,也就是一个工作负载Pod又是一组容器(Containers)所以关系又像是这样工作负载(Workloads)控制一组PodPod控制
我花了一些时间学习Ruby,我想转向一些GUI编程。GNOME3是目前最吸引我的环境,所以我想看看GTK+3。然而,GTK+3documentation’sGettingStartedexamples在C中非常令人反感。是否有不那么可怕的Ruby绑定(bind)(和HelloWorld示例)可用?编辑:GTK+LanguageBindingsoverview没有留下太多希望。 最佳答案 在freenode上的#ruby上快速聊天后,我了解到有针对GTK+3的绑定(bind)正在积极开发中:https://github.com/m
由Gnome维护的Javascript中GTK库的绑定(bind),它们是异步调用还是同步调用?我无法以任何一种方式找到详细信息。我想为GTK开发一个用于创建桌面应用程序的NodeJS模块。 最佳答案 在https://github.com/Tim-Smart/node-gtk处有静态gtk绑定(bind)的开始我开始绑定(bind)到位于https://github.com/creationix/node-gir的GObjectIntrospectionRepository.两者都不完整。我的目前只是一个路线图,但我已经与线下的人
我正在尝试使用gjs为gnome-shell创建简单的gtk应用程序。它的窗口只包含Gtk.TextView,我想在用户输入时处理事件。这是我的代码:#!/usr/bin/gjsvarGtk=imports.gi.Gtk;functionMainWindow(){this._init();}MainWindow.prototype={_init:function(){this.window=newGtk.Window({title:"JustCalculator",window_position:Gtk.WindowPosition.CENTER,default_height:400,
我正在使用GTKbindingsforGo.尝试将gtk.RadioButtontoggle信号连接到函数。此代码工作正常:...radioButton.Connect("toggled",doRadioToggle)funcdoRadioToggle(){fmt.Println("toggled")}...当切换radioButton时,调用doRadioToggle-很好。但是我想连接一个带参数的函数,例如:funcdoRadioToggle(button*gtk.RadioButton){fmt.Println(button.GetState())}gtk.go.Connect(
我对C的理解很差。我可以阅读代码,但我不知道如何包含/构建/制作/配置任何内容。这可能就是为什么我无法编译以下Go代码的原因。这段代码是我尝试改编https://developer.gnome.org/gtk3/3.0/gtk-getting-started.html去。packagemain//#cgopkg-config:gtk+-3.0//#includeimport"C"funcmain(){C.gtk_init(nil,nil)window:=C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL)C.g_signal_connect(window,"d
我正在使用GO-GTK来显示图像,该项目在amd64上运行良好,但是当我尝试为arm(RaspberryPi)交叉编译它时,出现以下错误。请告知如何将go-gtk从amd64交叉编译到arm(Raspberrypi3)。编译器输出如下github.com/mattn/go-gtk/glib#github.com/mattn/go-gtk/glibInfileincludedfrom/usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h:9:0,from/usr/include/glib-2.0/glib/gtypes.h:32,f
我是gtk编程的新手(但对python有经验)。我有一个带有按钮小部件子项的窗口。想让按钮完全填满窗口怎么办?顺便说一句,使用xml(fill-parent)这将非常容易,有没有类似于xml的gtk原生的东西?提前致谢! 最佳答案 在不知道你现在的程序是什么的情况下,我只能给出一个大概的答案。有两种方法可以解释您的第一个问题;我会回答这两个问题。GTK+中有两种类型的容器。第一个,bin,只有一个child,并且自动给那个child填充父级的整个大小。GtkWindow、GtkScrolledWindow、GtkFrame等都是bi
h大家好。在我的Linux机器上,我使用Glade3生成了一个XML文件。我成功地将XML文件嵌入到程序中,并使用以下命令编译了GTK+程序:gcc-Wall-g`pkg-config--cflags--libsgtk+-2.0`prog.c该程序完全符合我的要求。但是,在Windows上使用Cygwin,我无法编译它。我已经安装了MinGW和WindowsGTK+2.0包。它们都位于Z驱动器的根目录中。pkg-config工作正常,它向GCC发送了几个编译器和链接器选项。我没有收到任何“文件不存在”错误,并且我设置了$PATH。我收到了大约一打“未定义引用”错误。每次调用GTK函数时