十八、Gtk4-Stateful action

文章介绍了如何使用GSimpleAction创建具有状态的动作,如全屏切换和颜色选择。全屏菜单通过GSimpleAction的状态切换窗口的最大化和非最大化,颜色选择菜单则通过GVariant传递字符串参数来改变标签的背景颜色。GVariant可以存储不同类型的值,包括布尔值和字符串。信号处理程序如“change-state”和“activate”用于响应用户操作。文章还提供了示例代码来展示这些概念的实际应用。

有些动作action有状态。状态的典型值是布尔值或字符串。但是,如果你愿意,也可以使用其他类型的状态。

具有状态的动作称为有状态的。

Stateful action without a paramete

有些菜单被称为切换菜单。例如,全屏菜单有一个状态,它有两个值——全屏和非全屏。每次单击菜单时,状态的值都会改变。一个动作对应全屏菜单也有一个状态。它的值为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");
  • act_fullscreen是一个GSimpleAction实例。它是用g_simple_action_new_stateful创建的。这个函数有三个参数。第一个参数"fullscreen"是操作的名称。第二个参数是形参类型。NULL表示操作没有参数。第三个参数是动作的初始状态。它是一个GVariant值。下一小节将解释GVariant。函数g_variant_new_boolean (FALSE)返回一个GVariant值,即布尔值FALSE。如果有两个或更多的顶层窗口,每个窗口都有自己的act_fullscreen操作。因此,操作的数量与窗口的数量相同。
  • 连接动作act_fullscreen和“change-state”信号处理程序fullscreen_changed。如果单击全屏菜单,则激活相应的动作act_fullscreen。但没有处理器连接到"激活"信号。然后,对于具有NULL参数类型(如act_fullscreen)的布尔声明的操作,默认行为是通过“change-state”信号切换它们。
  • 该操作被添加到GtkWindow win中。因此,行动的范围是 “win” – window。
  • menu_item_fullscreen是一个GMenuItem实例。有两个参数。第一个参数"Full Screen"是menu_item_fullscreen的标签。第二个参数是一个动作。动作“赢”。Fullscreen “前缀是"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 }
  • fullscreen_changed处理程序有三个参数。第一个参数是发出“change-state”信号的动作。第二个参数是操作的新状态的值。第三个参数是一个用户数据,在g_signal_connect中设置。
  • 如果值是布尔类型且为TRUE,则最大化窗口;否则unmaximizes。
  • 用value设置操作的状态。注意:第二个参数是切换后的状态值,但在此阶段,操作的状态具有原始值。因此,您需要通过g_simple_action_set_state用新值设置状态。

你可以使用“activate”信号代替“change-state”信号,或者同时使用两种信号。但上面的方法是最简单也是最好的。

GVariant

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不能更改。

Stateful action with a parameter

另一个有状态操作的例子是与颜色选择菜单相对应的操作。例如,有三个菜单,每个菜单分别有红色、绿色和蓝色。它们确定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"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值