二十四、Gtk4-GtkExpression

news2024/11/25 16:44:47

GtkExpression是一种基本类型。它不是GObject的后代。GtkExpression提供了一种描述对值的引用的方法。GtkExpression需要求值才能获得值。

它类似于算术计算。

1 + 2 = 3

1+2是一个表达式。给出了计算的方法。3是来自表达式的值。求值是计算表达式并得到值。

GtkExpression是一种获取值的方法。Evaluation类似于计算。值是通过计算表达式得到的。

Constant expression

常量表达式(GtkConstantExpression)在求值时提供常量值或实例。

  GValue value = G_VALUE_INIT;
  expression = gtk_constant_expression_new (G_TYPE_INT,100);
  gtk_expression_evaluate (expression, NULL, &value);
  • GtkExpression使用GValue来保存一个值。GValue是一个保存类型和值的结构体和容器。它必须首先用G_VALUE_INIT初始化。注意,value是结构体,而不是指向结构体的指针。
  • 常量表达式用gtk_constant_expression_new函数创建。函数的参数是一个类型(GType)和一个值(或实例)。这个表达式保存一个常量值。G_TYPE_INT是注册到类型系统的类型。整数类型。下表列出了一些类型。
  • gtk_expression_evaluate计算表达式的值。它有三个参数:要求值的表达式、这个实例和一个指向GValue的指针。对于常量表达式来说,这个实例不是必需的。因此,第二个参数是NULL。如果成功计算表达式,gtk_expression_evaluate返回TRUE。否则返回FALSE。
  • 如果返回TRUE,则用表达式的值设置GValue的值。值的类型是int。

请添加图片描述
src/expression目录下有一个示例程序exp_constant_simple.c。

  • 9 .创建常量表达式。它保存一个int值100。变量表达式指向表达式。
  • 11-14:对表达式求值。如果成功,将值显示给stdout。否则显示错误消息。
  • 15-16:释放表达式并取消设置GValue。

常量表达式通常用于将常量值或实例赋给另一个表达式。

Property expression

属性表达式(GtkPropertyExpression)在GObject实例中查找属性。例如,引用GtkLabel对象中的“label”属性的属性表达式是这样创建的。

expression = gtk_property_expression_new (GTK_TYPE_LABEL, another_expression, "label");

第二个形参another_expression是:

  • 在求值时给出GtkLabel实例的表达式。
  • NULL.当给定NULL时,求值时会给出一个GtkLabel实例。这个实例被称为这个对象。

例如,

label = gtk_label_new ("Hello");
another_expression = gtk_constant_expression_new (GTK_TYPE_LABEL, label);
expression = gtk_property_expression_new (GTK_TYPE_LABEL, another_expression, "label");

如果expression被求值,第二个参数another_expression会被提前求值。another_expression的值是标签(GtkLabel实例)。然后,expression查找标签的"label"属性和求值结果"Hello"。

在上面的例子中,gtk_property_expression_new的第二个参数是另一个表达式。但是第二个参数可以是NULL。如果为NULL,则使用这个实例。这由gtk_expression_evaluate函数给出。

在src/expression目录下有一个简单的程序exp_property_simple.c。

 1 #include <gtk/gtk.h>
 2 
 3 int
 4 main (int argc, char **argv) {
 5   GtkWidget *label;
 6   GtkExpression *expression;
 7   GValue value = G_VALUE_INIT;
 8 
 9   gtk_init ();
10   label = gtk_label_new ("Hello world.");
11   /* Create an expression */
12   expression = gtk_property_expression_new (GTK_TYPE_LABEL, NULL, "label");
13   /* Evaluate the expression */
14   if (gtk_expression_evaluate (expression, label, &value))
15     g_print ("The value is %s.\n", g_value_get_string (&value));
16   else
17     g_print ("The constant expression wasn't evaluated correctly.\n");
18   gtk_expression_unref (expression);
19   g_value_unset (&value);
20 
21   return 0;
22 }
  • 9-10: gtk_init初始化GTK GUI工具包。这通常是不必要的,因为GtkApplication默认的启动处理程序会进行初始化。一个GtkLabel实例被创建为"Hello world."。
  • 12:创建属性表达式。它看起来像一个GtkLabel实例的“label”属性。但在创建时,没有给出实例,因为第二个参数是NULL。该表达式只知道如何从给定future的GtkLabel实例中获取属性。
  • 14-17:函数gtk_expression_evaluate使用this实例标签来计算表达式。结果保存在GValue值中。函数g_value_get_string从GValue中获取一个字符串。但是字符串属于GValue,所以不能释放字符串。
  • 18-19:释放表达式并取消设置GValue。与此同时,GValue中的字符串被释放。

如果gtk_property_expression_new的第二个参数不是NULL,那么它就是另一个表达式。该表达式由新创建的属性表达式拥有。所以,当表达式无用时,你只需释放最后一个表达式。然后释放它拥有的另一个表达式。

Clousure expression

闭包表达式在计算闭包时调用闭包。闭包是回调函数(一个指向函数的指针)的通用表示。有关闭包的信息,请参阅GObject API参考——GObject消息系统。在src/expression目录下有一些简单的闭包示例文件closure.c和closure_each.c。

有两种闭包表达式,GtkCClosureExpression 和GtkClosureExpression。它们分别对应于GCClosure和GClosure。当你用C语言编程时,GtkCClosureExpression和GCClosure是合适的。

闭包表达式是用gtk_closure_expression_new函数创建的。

GtkExpression *
gtk_cclosure_expression_new (GType value_type,
                             GClosureMarshal marshal,
                             guint n_params,
                             GtkExpression **params,
                             GCallback callback_func,
                             gpointer user_data,
                             GClosureNotify user_destroy);
  • value_type是求值时值的类型。
  • marshal就是marshaller。你可以赋值NULL。如果它是NULL,那么g_cclosure_marshal_generic()被用作marshaller。它是一个通过libffi实现的通用marshaller函数。
  • n_params是参数的数目。
  • params指出了回调函数中每个参数的表达式。
  • callback_func是一个回调函数。它被给出了这个参数和上面的参数。因此,如果n_params为3,则函数的参数数量为4。(this和params。见下文)。
  • user_data是用户数据。你可以把它添加到闭包中。它类似于g_signal_connect中的user_data。如果没有必要,则赋值NULL。
  • user_destroy是user_data的销毁通知。在不再需要user_data时,调用该函数销毁它。如果将NULL赋值给user_data,也将NULL赋值给user_destroy。

回调函数的格式如下。

C-type
callback (this, param1, param2, …)

int
callback (GObject *object, int x, const char *s)
  • 3-11:回调函数。这个参数只有一个,而且是一个this对象。它是一个GtkLabel,其标签被假定为"(number)+(number)"。
  • 8-10:从标签中检索两个整数,并返回它们的和。此函数没有错误报告。如果要返回错误报告,将返回值类型更改为指向gboolean和integer结构的指针。一个表示误差,另一个表示求和。gtk_cclosure_expression_new的第一个参数是G_TYPE_POINTER。在src/expression目录下有一个示例程序exp_closure_with_error_report。
  • 19: gtk_init初始化GTK。这对于GtkLabel是必要的。
  • 20:创建一个“123+456”的GtkLabel实例。
  • 21:实例具有浮动引用。它变成了一个普通的引用计数。
  • 22-23:创建闭包表达式。它的返回值类型是G_TYPE_INT,没 有参数或“this”对象。
  • 24:将标签作为this对象来计算表达式。
  • 25:如果计算成功,显示“123+456”的和。它是579。
  • 27:如果失败,显示错误信息。
  • 28-30:释放expression和标签。重置该值。

闭包表达式比其他类型的表达式更灵活,因为你可以指定自己的回调函数。

GtkExpressionWatch

GtkExpressionWatch是一个结构体,而不是对象。它表示一个被监视的gtk表达式。两个函数创建了GtkExpressionWatch结构。

gtk_expression_bind function

这个函数将目标对象的属性绑定到表达式上。如果表达式的值改变了,属性会立即反映这个值。

GtkExpressionWatch*
gtk_expression_bind (
  GtkExpression* self,
  GObject* target,
  const char* property,
  GObject* this_
)

这个函数接受表达式的所有权。因此,如果你想拥有表达式,可以调用gtk_expression_ref()来增加表达式的引用计数。当它没用的时候,你应该取消引用。如果你不拥有这个表达式,你就不在乎释放这个表达式。
在这里插入图片描述

一个exp_bind.c和exp_bind的例子。UI位于src/expression目录中。

它包括一个label和一个scale。如果向右移动滑块,scale值会增加,标签上的数字也会增加。同样地,如果向左移动,标签上的数字就会减少。标签通过调整绑定到scale值上。

 1 <?xml version='1.0' encoding='UTF-8'?>
 2 <interface>
 3   <object class='GtkApplicationWindow' id='win'>
 4     <property name='default-width'>600</property>
 5     <child>
 6       <object class='GtkBox'>
 7         <property name='orientation'>GTK_ORIENTATION_VERTICAL</property>
 8         <child>
 9           <object class='GtkLabel' id='label'>
10             <property name="label">10</property>
11           </object>
12         </child>
13         <child>
14           <object class='GtkScale'>
15             <property name='adjustment'>
16               <object class='GtkAdjustment' id='adjustment'>
17                 <property name='upper'>20.0</property>
18                 <property name='lower'>0.0</property>
19                 <property name='value'>10.0</property>
20                 <property name='step-increment'>1.0</property>
21                 <property name='page-increment'>5.0</property>
22                 <property name='page-size'>0.0</property>
23               </object>
24             </property>
25             <property name='digits'>0</property>
26             <property name='draw-value'>true</property>
27             <property name='has-origin'>true</property>
28             <property name='round-digits'>0</property>
29           </object>
30         </child>
31       </object>
32     </child>
33   </object>
34 </interface>

ui文件描述了以下父子关系。

GtkApplicationWindow (win) -- GtkBox -+- GtkLabel (label)
                                      +- GtkScale

定义了4个GtkScale属性。

  • adjustment。GtkAdjustment提供如下功能。
    • upper and lower:scle的范围。
    • value:scale的当前值。它反映了scale的当前值。
    • step increment and page increment:当用户按箭头键或页面上/下键时,缩放比例分别以 step increment和page increment的方式移动。
    • page-size:当与比例一起使用时,page-size为0。
  • digits:数值中显示的小数位数。
  • draw-value:值是否显示。
  • has-origin:标尺是否有原点。如果它为真,则在原点和当前点之间出现橙色条。
  • round-digits:数值发生变化时舍入的位数。例如,如果它为0,则滑块移动到一个整数点。
 1 #include <gtk/gtk.h>
2 
3 GtkExpressionWatch *watch;
4 
5 static int
6 f2i (GObject *object, double d) {
7   return (int) d;
8 }
9 
10 static int
11 close_request_cb (GtkWindow *win) {
12   gtk_expression_watch_unwatch (watch);
13   return false;
14 }
15 
16 static void
17 app_activate (GApplication *application) {
18   GtkApplication *app = GTK_APPLICATION (application);
19   gtk_window_present (gtk_application_get_active_window(app));
20 }
21 
22 static void
23 app_startup (GApplication *application) {
24   GtkApplication *app = GTK_APPLICATION (application);
25   GtkBuilder *build;
26   GtkWidget *win, *label;
27   GtkAdjustment *adjustment;
28   GtkExpression *expression, *params[1];
29 
30   /* Builds a window with exp.ui resource */
31   build = gtk_builder_new_from_file ("exp_bind.ui");
32   win = GTK_WIDGET (gtk_builder_get_object (build, "win"));
33   label = GTK_WIDGET (gtk_builder_get_object (build, "label"));
34   // scale = GTK_WIDGET (gtk_builder_get_object (build, "scale"));
35   adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (build, "adjustment"));
36   gtk_window_set_application (GTK_WINDOW (win), app);
37   g_signal_connect (win, "close-request", G_CALLBACK (close_request_cb), NULL);
38   g_object_unref (build);
39 
40   /* GtkExpressionWatch */
41   params[0] = gtk_property_expression_new (GTK_TYPE_ADJUSTMENT, NULL, "value");
42   expression = gtk_cclosure_expression_new (G_TYPE_INT, NULL, 1, params, G_CALLBACK (f2i), NULL, NULL);
43   watch = gtk_expression_bind (expression, label, "label", adjustment); /* watch takes the ownership of the expression. */
44 }
45 
46 #define APPLICATION_ID "com.github.ToshioCP.exp_watch"
47 
48 int
49 main (int argc, char **argv) {
50   GtkApplication *app;
51   int stat;
52 
53   app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
54 
55   g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
56   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
57 
58   stat =g_application_run (G_APPLICATION (app), argc, argv);
59   g_object_unref (app);
60   return stat;
61 }
  • 41-42:定义两个表达式。一个是属性表达式,另一个是闭包表达式。属性表达式查找调整实例的“value”属性。闭包表达式只是将double转换为整数。
  • 43: gtk_expression_bind将GtkLabel实例的label属性绑定到闭包表达式返回的整数上。它创建了一个GtkExpressionWatch结构。绑定在watch生命周期内工作。当窗口被销毁时,scale和adjustment也被破坏。watch识别出expression变化的value,并试图改变标签的属性。显然,这不是正确的行为。在窗户被破坏之前,watch应该无人看管。
  • 37:将窗口上的“关闭请求”信号连接到处理程序close_request_cb。这个信号在单击关闭按钮时发出。处理程序在窗口关闭前被调用。现在正是让GtkExpressionWatch无人观看的好时机。
  • 10-14:“close-request”信号处理程序。Gtk_expression_watch_unwatch (watch)使手表停止观察表达式。它释放表达式并在其中调用gtk_expression_watch_unref (watch)。

如果您想将属性绑定到表达式,gtk_expression_bind是最佳选择。你可以用gtk_expression_watch函数来实现,但它不太适合。

gtk_expression_watch function

Gtkexpression in ui files

Conversion between GValues

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大厂高频真题100题】《有效的井字游戏》 真题练习第26题 持续更新~

有效的井字游戏 给你一个字符串数组 board 表示井字游戏的棋盘。当且仅当在井字游戏过程中,棋盘有可能达到 board 所显示的状态时,才返回 true 。 井字游戏的棋盘是一个 3 x 3 数组,由字符 ,X 和 O 组成。字符 代表一个空位。 以下是井字游戏的规则: 玩家轮流将字符…

CODESYS开发教程10-文件读写(SysFile库)

今天继续我们的小白教程&#xff0c;老鸟就不要在这浪费时间了&#x1f60a;。 前面一期我们介绍了CODESYS的文件操作库CAA File。这一期主要介绍CODESYS的SysFile库所包含的文件读写功能块&#xff0c;主要包括文件路径、名称、大小的获取以及文件的创建、打开、读、写、拷贝…

mysql数据库安装

三种安装方式 tar -xf mysql-5.7.37-linux-glibc2.12-x86_64.tar.gz [rootsc-mysql opt]# tar -xf mysql-5.7.37-linux-glibc2.12-x86_64.tar.gz [rootsc-mysql opt]# ls apache-zookeeper-3.6.3-bin kafka_2.12-2.8.1.tgz apache-zookeeper-3.6.3-bin.tar.gz mysql…

无线局域网

无线局域网&#xff08;Wireless Local Ara Network&#xff0c;WLAN&#xff09; 一、无线局域网的组成 无线局域网可分为两大类&#xff1a;&#xff08;1&#xff09;有基础设施的&#xff1b;&#xff08;2&#xff09;无基础设施的。 1. IEEE802.11 对于有基础设施的无…

Spring boot 实战指南(三):整合Elasticsearch、swagger、redis、mq

文章目录一、Elasticsearch创建项目配置maven完善依赖es连接配置实体映射repositoryservicecontroller二、swagger依赖启动类路径匹配配置配置类controller注解三、redis一、Elasticsearch 官方文档 Elasticsearch教程 自己搭建了一个简单的demo&#xff0c;仓库在这里&#…

分布式之CAP理论分析

写在前面 任何存在的事物都有其内在的特性&#xff0c;分布式也不例外&#xff0c;那么分布式都有什么特性呢&#xff1f;国外有大牛就帮我们总结了如下的三点&#xff1a; C:Consitency,一致性 A&#xff1a;Available&#xff0c;可用性 P&#xff1a;Partition tolerance&…

细讲一个 TCP 连接能发多少个 HTTP 请求(二)

第三个问题&#xff1a;一个 TCP 连接中 HTTP 请求发送可以一起发送么&#xff08;比如一起发三个请求&#xff0c;再三个响应一起接收&#xff09;&#xff1f; HTTP/1.1 存在一个问题&#xff0c;单个 TCP 连接在同一时刻只能处理一个请求&#xff0c;意思是说&#xff1a;两…

测试员都是背锅侠?测试人员避“锅”攻略,拿走不谢

最近发生了一起生产事故&#xff0c;究其根源&#xff0c;事故本身属于架构或者需求层面需要规避的问题&#xff0c;测试人员的责任其实是非常小的&#xff0c;但实际情况是&#xff1a;相关测试人员因此承担了很大的压力&#xff0c;成为质量问题的“背锅侠”。 实际上&#…

极验2代验证码分析

目标链接 aHR0cDovL3d3dy5qc2dzai5nb3YuY246NTg4ODgvbWluaS9uZXR3ZWIvU01MaWJyYXJ5LmpzcA接口分析 点击搜索就会跳出验证码&#xff0c;netWebServlet.json 的请求&#xff0c;会返回 challenge 和 gt 接着可以看响应请求图片信息的接口&#xff0c;可以看到请求参数包含cha…

iOS 组件化或SDK时对资源加载注意点

本文针对cocoapods进行打包的资源做个讲解&#xff0c;针对自身项目注意调整资源访问策略。 资源文件打包方式 使用pod lib create AppResourceModule 来进行演示。 use_frameworks! target AppResourceModule_Example dopod AppResourceModule, :path > ../ end podfil…

Python+Flask+MySQL开发的在线外卖订餐系统(附源码)

文章目录一、项目模块及功能介绍1、登录模块2、注册模块3、商家用户模块4、买家用户模块5、系统管理员模块源码二、项目结构三、环境依赖四、运行方法五、系统部分界面展示1、首页2、注册界面3、登录界面4、商家主界面5、商家菜单界面6、商家添加菜品界面7、商家修改菜品界面8、…

数值程序分析

原文来自微信公众号“编程语言Lab”&#xff1a;数值程序分析 搜索关注“编程语言Lab”公众号&#xff08;HW-PLLab&#xff09;获取编程语言更多技术内容&#xff01; 欢迎加入编程语言社区 SIG-程序分析&#xff0c;了解更多程序分析相关的技术内容。 加入方式&#xff1a;添…

实现自动化部署前端项目,从安装Jenkins到部署完成的整体配置 --适合初学Jenkins、想实现或者学习自动化部署的同学,知识点比较全面,过程写的清晰

前言 一、什么是Jenkins 二、Jenkins安装配置 Linux环境安装JDK Linux环境安装Maven Linux安装Jenkins 启动Jenkins jenkins配置 配置汉化版的jenkins 安装gitHub插件 gitHub配置 jenkins的配置 jenkins的gitHub配置 jenkins的java环境配置 小总结 两种情况 第…

RPCMon:一款基于ETW的RPC监控工具

关于RPCMon RPCMon是一款基于事件跟踪的WindowsRPC监控工具&#xff0c;该工具是一款GUI工具&#xff0c;可以帮助广大研究人员通过ETW&#xff08;Event Tracing for Windows&#xff09;扫描RPC通信。 RPCMon能够为广大研究人员提供进程之间RPC通信的高级视图&#xff0c;该…

谋变2023:家电巨头进击的“三大关口”

2022年的中国家电行业&#xff0c;无疑在艰难中前行。奥维云网&#xff08;AVC&#xff09;推总数据显示&#xff0c;2022年中国家电市场&#xff08;不含3C&#xff09;零售额为7081亿元&#xff0c;同比下滑7.4%。下滑背后的推力是多样的&#xff0c;包括地产市场下行、消费者…

服务端返回内容跨域CORS之后,也在chrome/edge浏览器里显示出响应信息

由于浏览器的同源策略&#xff0c;服务端返回的内容跨域&#xff0c;且没有允许跨域CORS的请求头之后&#xff0c;浏览器无法显示出服务端返回的信息&#xff0c;不方便问题排查。比如&#xff1a;Access to XMLHttpRequest at http://localhost:6001/service-app/query/common…

springcloud-工程创建(IDEA)

文章目录介绍springcloud 常用组件1.创建父工程2.删除父工程的src目录3.修改父工程的pom文件4 springcloud 版本依赖5.创建子模块6 子项目下创建启动类介绍 Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具&#xff0c;它为开发中的配置管理、服务发现、断路器、智…

最全面的内网open虚拟专用网络通道搭建过程

内网open虚拟专用网络通道搭建过程 文章目录内网open虚拟专用网络通道搭建过程前言一、环境准备二、安装open虚拟专用通道2.1、安装依赖包2.2、开始安装三、证书配置3.1、easy-rsa配置修改3.2、初始化与创建CA根证书3.3、生成服务端证书3.4、生成客户端证书3.5、创建服务端配置…

SpringCloud微服务~面试题

1. SpringCloud常见组件有哪些&#xff1f; 问题说明&#xff1a;这个题目主要考察对SpringCloud的组件基本了解 难易程度&#xff1a;简单 参考话术&#xff1a; SpringCloud包含的组件很多&#xff0c;有很多功能是重复的。其中最常用组件包括&#xff1a; 注册中心组件&…

【冲刺金三银四】2023年网络安全工程师面试题合集

以下为信息/网络安全各个方向涉及的面试题&#xff0c;星数越多代表问题出现的几率越大&#xff0c;祝各位都能找到满意的工作~ 【一一帮助网络安全提升点我一一】 ①网络安全学习路线 ②20份渗透测试电子书 ③安全攻防357页笔记 ④50份安全攻防面试指南 ⑤安全红队渗透工具包 …