二、GtkApplication and GtkApplicationWindow

news2024/11/26 18:40:16

1 GtkApplication

1.1 GtkApplication and g_application_run

人们编写编程代码来开发应用程序。什么是应用程序?应用程序是使用库运行的软件,其中包括操作系统、框架等。在GTK 4编程中,GTK应用程序是使用GTK库运行的程序(或可执行程序)。

编写GtkApplication的基本方法如下。

  • 创建一个GtkApplication实例。
  • 运行这个实例。

这是所有。非常简单。下面是代表上述方法的C代码。

 1 #include <gtk/gtk.h>
 2 
 3 int
 4 main (int argc, char **argv) {
 5   GtkApplication *app;
 6   int stat;
 7 
 8   app = gtk_application_new ("com.github.ToshioCP.pr1", G_APPLICATION_DEFAULT_FLAGS);
 9   stat =g_application_run (G_APPLICATION (app), argc, argv);
10   g_object_unref (app);
11   return stat;
12 }
13 

第一行说明这个程序包含Gtk库的头文件。函数main是C语言中的一个启动函数。变量app被定义为一个指向GtkApplication实例的指针。函数gtk_application_new创建一个GtkApplication实例,并返回一个指向该实例的指针。GtkApplication实例是一个C结构体数据,其中存储了有关应用程序的信息。后面会解释这些参数的含义。函数g_application_run运行实例定义的应用程序。(我们经常说这个函数运行app。实际上,app不是一个应用程序,而是一个指向该应用程序实例的指针。但是,它简单而简短,可能不会造成混淆。)

这里我使用了单词instance。实例、类和对象是面向对象编程中的术语。我用同样的方式使用这些词。但是,在本教程中,我将经常使用“对象”而不是“实例”。这意味着“对象”和“实例”是相同的。对象是一个有点模棱两可的词。从广义上讲,对象比实例具有更广泛的含义。因此,读者应注意语境,以找到“对象”的含义。在很多情况下,object和instance是相同的。

要编译它,需要运行以下命令。字符串pr1.c是上述C源代码的文件名。

gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`

./a.out
(a.out:13533): GLib-GIO-WARNING **: 15:30:17.449: Your application does not implement
g_application_activate() and has no handlers connected to the “activate” signal.
It should do one of these.

哦,它只是产生一个错误信息。这个错误消息意味着GtkApplication对象运行了,毫无疑问。现在,让我们想想这条消息意味着什么。

1.2 信号

这个消息告诉我们:

  1. 应用程序GtkApplication没有实现g_application_activate(),
  2. 它没有连接到“activate”信号的处理程序,而且
  3. 你需要解决其中至少一个问题。

这两个error的原因与信号有关。我先给你们解释一下。

当有事情发生时,就会发出信号。例如,创建窗口,销毁窗口,等等。当应用被激活时,会发出"activate"信号。(Activated和started有点不同,但你可以认为到目前为止两者几乎是一样的。)如果信号连接到一个函数,该函数被称为信号处理程序或简单地称为处理程序,那么在信号发出时将调用该函数。

流程是这样的:

  1. 一些事情发生。
  2. 如果它与某个信号相关,那么这个信号就会被发射出来。
  3. 如果信号预先连接到某个处理程序,则调用该处理程序。

信号在对象中定义。例如,“activate”信号属于GApplication对象,它是GtkApplication对象的父对象(注意GApplication和GtkApplication区别)。

GApplication对象是GObject对象的子对象。GObject是所有对象层次结构中的顶层对象。

GObject -- GApplication -- GtkApplication
<---parent                      --->child

子对象从父对象继承信号、函数、属性等。因此,GtkApplication也有“activate”信号。

现在我们可以解决pr1.c中的问题。我们需要将“activate”信号连接到一个处理程序。我们使用函数g_signal_connect将信号连接到处理程序。

 1 #include <gtk/gtk.h>
 2 
 3 static void
 4 app_activate (GApplication *app, gpointer *user_data) {
 5   g_print ("GtkApplication is activated.\n");
 6 }
 7 
 8 int
 9 main (int argc, char **argv) {
10   GtkApplication *app;
11   int stat;
12 
13   app = gtk_application_new ("com.github.ToshioCP.pr2", G_APPLICATION_DEFAULT_FLAGS);
14   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
15   stat =g_application_run (G_APPLICATION (app), argc, argv);
16   g_object_unref (app);
17   return stat;
18 }
19 

首先,我们定义处理程序app_activate,它只是显示一条消息。函数g_print是在GLib中定义的,它类似于C标准库中的printf。在函数main中,我们在g_application_run之前添加g_signal_connect。函数g_signal_connect有4个参数。

  • 信号所属的实例。
  • 信号的名称。
  • 一个处理程序函数(也称为callback),需要用G_CALLBACK强制转换。
  • 传递给处理程序的数据。如果没有必要的数据,则应该给出NULL。

在GObject API参考中有描述。正确地说,g_signal_connect是一个宏(不是C函数)。

#define g_signal_connect(instance, detailed_signal, c_handler, data) \
    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)

你可以在API参考手册中找到每个信号的描述。例如,“activate”信号位于GIO API参考中的GApplication部分。

void
activate (
  GApplication* self,
  gpointer user_data
)

这是一个“activate”信号处理程序的声明。你可以使用任何名称来代替上面声明中的“activate”。参数有:

  • self是信号所属的实例。
  • user_data是g_signal_connect函数的第四个参数中定义的数据。如果它是NULL,那么你可以忽略并省略第二个参数。

API参考手册非常重要。你应该看到并理解它。

让我们编译上面的源文件(pr2.c)并运行它。

$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
$ ./a.out
GtkApplication is activated.
$

好的,做得好。然而,你可能已经注意到,输入这么长的代码行来编译是很痛苦的。使用shell脚本来解决这个问题是个好主意。创建一个文本文件,其中包含下面一行。

gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`

然后,将其保存在$HOME/bin目录下,通常是/ HOME/(用户名)/bin。(如果用户名为James,则目录为/home/james/bin)。然后打开文件的执行位。如果文件名是comp,这样做:

$ chmod 755 $HOME/bin/comp
$ ls -log $HOME/bin
    ...  ...  ...
-rwxr-xr-x 1   62 May 23 08:21 comp
    ...  ...  ...

如果这是第一次创建$HOME/bin目录并保存文件,则需要注销并重新登录。

$ comp pr2
$ ./a.out
GtkApplication is activated.
$

2 GtkWindow and GtkApplicationWindow

2.1 GtkWindow

在前面的小节中打印了一条消息“GtkApplication is activated.”。就gtk应用程序的测试而言,它是很好的。然而,由于Gtk是图形用户界面(GUI)的框架,因此它是不够的。现在我们继续在这个程序中添加一个窗口。我们需要做的是:

  • 创建一个GtkWindow。
  • 将它连接到GtkApplication。
  • 显示窗口。

现在重写函数app_activate。

创建一个GtkWindow

1 static void
2 app_activate (GApplication *app, gpointer user_data) {
3   GtkWidget *win;
4 
5   win = gtk_window_new ();
6   gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));
7   gtk_window_present (GTK_WINDOW (win));
8 }

Widget是一个抽象的概念,它包括所有GUI界面,如窗口、对话框、按钮、多行文本、容器等。GtkWidget是所有GUI对象的派生对象的基类。

parent <-----> child
GtkWidget -- GtkWindow

GtkWindow顶部成员就是GtkWidget

在这里插入图片描述
函数gtk_window_new的定义如下。

GtkWidget *
gtk_window_new (void);

根据这个定义,它返回一个指向GtkWidget的指针,而不是GtkWindow。它实际上创建了一个新的GtkWindow实例(不是GtkWidget),但返回了一个指向GtkWidget的指针。但是,该指针指向GtkWidget,同时它也指向包含GtkWidget的GtkWindow。

如果您想将win用作指向GtkWindow类型实例的指针,则需要对其进行强制转换。

(GtkWindow *) win

它可以工作,但通常不被使用。相反,使用GTK_WINDOW宏。

GTK_WINDOW (win)

推荐使用宏,因为它不仅转换,还检查类型。

连接win到GtkApplication

函数gtk_window_set_application用于将GtkWindow连接到GtkApplication。

gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));

您需要用GTK_WINDOW宏把win转换到GtkWindow型指针,用GTK_WINDOW宏把app转换到GtkApplication型指针。

GtkApplication会继续运行,直到相关的窗口被销毁。如果你没有连接GtkWindow和GtkApplication, GtkApplication会立即销毁自己。因为没有窗口连接到GtkApplication,所以GtkApplication不需要等待任何东西。因为它会销毁自己,所以GtkWindow也会被销毁。

显示窗口

函数gtk_window_present将窗口呈现给用户(显示给用户)。

GTK4 将默认的小部件可见性更改为on,因此每个小部件都不需要将其更改为on。但是,有一个例外。顶层窗口(稍后解释)在创建时是不可见的。所以你需要使用上面的函数来显示窗口。

你可以使用gtk_widget_set_visible (win, true)代替gtk_window_present。但是这两者的行为是不同的。假设屏幕上有两个windows win1和win2, win1在win2后面。两个窗口都是可见的。函数gtk_widget_set_visible (win1, true)什么也不做,因为win1已经是可见的。所以win1仍然落后于win2。另一个函数gtk_window_present (win1)将win1移动到windows栈的顶部。因此,如果想显示窗口,应该使用gtk_window_present。

两个函数gtk_widget_show和gtk_widget_hide自GTK 4.10以来已被弃用。您应该使用gtk_widget_set_visible.

将程序保存为pr3.c,然后编译并运行它。

保存程序为pr3.c,这时编译运行它:

$ comp pr3
$ ./a.out

一个小窗口将会出现。

在这里插入图片描述
单击关闭按钮,然后窗口消失,程序结束。

2.2 GtkApplicationWindow

GtkApplicationWindow是GtkWindow的一个子对象。它有一些额外的功能,可以更好地与GtkApplication集成。建议将它用作应用程序的顶层窗口,而不是GtkWindow。

现在重写程序并使用GtkApplicationWindow。

1 static void
2 app_activate (GApplication *app, gpointer user_data) {
3   GtkWidget *win;
4 
5   win = gtk_application_window_new (GTK_APPLICATION (app));
6   gtk_window_set_title (GTK_WINDOW (win), "pr4");
7   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
8   gtk_window_present (GTK_WINDOW (win));
9 }

当您创建GtkApplicationWindow时,您需要提供GtkApplication实例作为参数。然后它自动连接这两个实例。所以你不需要再调用gtk_window_set_application了。

该程序设置窗口的标题和默认大小。编译并运行a.out,你会看到一个标题为"pr4"的大窗口。

在这里插入图片描述
参考:Gtk4-tutorial sec3: GtkApplication and GtkApplicationWindow

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

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

相关文章

屏幕录制有快捷键吗?录屏快捷键ctrl加什么

我们日常使用的电脑是自带录屏功能&#xff0c;可以方便我们将玩游戏的精彩画面&#xff0c;或者是电影某个片段给录制下来。为了不错过这些精彩片段&#xff0c;可以使用录屏快捷键录制。那电脑录屏快捷键ctrl加什么&#xff1f;今天本文就简单地给大家介绍电脑录屏快捷键&…

【错误记录】IntelliJ IDEA 编译 Java 文件报错 ( 错误: 非法字符: ‘\ufeff‘ )

文章目录一、报错信息二、修改方案一、报错信息 报错信息 : D:\002_Project\003_Java_Work\Xxx\src\main\java\cn\Xxx.java:1: 错误: 非法字符: \ufeff &#xfeff;package xxx;出现该问题的原因是 IntelliJ IDEA 在创建文件时 , 为文件添加了 BOM 隐藏字符 , 这是 文件的 字…

(七)汇编语言——更灵活的定位内存地址的方法

目录 and和or ASCII码 [bxidata] SI和DI寄存器 [bxsi]和[bxdi] [bxsiidata]和[bxdiidata] 总结 例子&#xff08;双重循环的解决方案&#xff09; 我们知道&#xff0c;对于汇编来说&#xff0c;内存是极为重要的&#xff0c;所以&#xff0c;能精准且巧妙地定位内存地…

进程间通信——信号

目录 1 概念 2 信号类型 linux的基本信号类型 操作 常用的信号 3 怎么操作信号 signal kill raise alarm pause 注意 范例1&#xff08;自己用信号发送书写sleep函数实现定时炸弹&#xff09; 范例2&#xff08;用信号发送书写功能检测用户是否输入&#xff0c;如…

OAuth2.0协议流程与授权模式、协议流程

什么是OAuth2.0OAuth&#xff08;Open Authorization&#xff09;是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户名和密码提供给第三方移动应用或分…

Java 如何优雅的导出 Excel

前言 公司项目最近有一个需要&#xff1a;报表导出。整个系统下来&#xff0c;起码超过一百张报表需要导出。这个时候如何优雅的实现报表导出&#xff0c;释放生产力就显得很重要了。下面主要给大家分享一下该工具类的使用方法与实现思路。 实现的功能点 对于每个报表都相同…

看零信任如何基于PKI体系实现数字信任

谈到安全&#xff0c;在万物互联的数字世界里&#xff0c;生活和工作之间的界限正在变得越来越模糊&#xff0c;传统的边界不再适用&#xff0c;传统的安全手段也不再适用。数字转型的步伐虽在不断加速&#xff0c;但威胁载体也在不断发展壮大&#xff0c;在数字互动过程中&…

从0到1完成一个Vue后台管理项目(三、使用SCSS/LESS,安装图标库)

往期 从0到1完成一个Vue后台管理项目&#xff08;一、创建项目&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;二、使用element-ui&#xff09; 安装CSS预处理器 Sass cnpm i sass-loader7 node-sass4 -S 安装完就可以使用了&#xff0c;通过lang的方式 这里注意自…

C#,桌面编程入门(01)——按钮Button属性与事件、动态创建、快捷键、控件数组及自定义Button

本文是《桌面编程入门》系列文章的开山之篇。《桌面编程入门》系列文章主要介绍桌面编程的各种组件&#xff0c;Button&#xff0c;ComboBox&#xff0c;Panel&#xff0c;WebBrowser。。。。。。类似的文章非常多&#xff0c;深度不同&#xff0c;水平不等。1 桌面编程1.1 图形…

第六天作业部分

使用的文件内容 1&#xff1a;passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shut…

0. 【R、Rstudio、Rtools 】软件的安装 + 在Rstudio上永久修改(默认工作路径 + 默认安装包路径)

文章目录1.R软件安装2. Rstudio的安装3. Rtools 的安装4. 初始化Rstudio4.1 更改Rtudio的镜像为中国清华大学&#xff0c;下载包更快4.2. 修改默认工作路径 默认安装包路径全部都在官网下&#xff0c;都是免费的 1.R软件安装 访问官网&#xff1a;https://www.r-project.org/ …

React(coderwhy)- 04(css)

React中CSS的概述 组件化天下的CSS ◼ 前面说过&#xff0c;整个前端已经是组件化的天下&#xff1a;  而CSS的设计就不是为组件化而生的&#xff0c;所以在目前组件化的框架中都在需要一种合适的CSS解决方案。 ◼ 在组件化中选择合适的CSS解决方案应该符合以下条件&#xff…

为外贸软件花钱前,需要考虑的几大因素

当外贸企业发展壮大到一定程度时&#xff0c;购买一款适合公司、产品、业务的办公软件帮助员工更好的处理工作是必然的选择。如何挑选一款真正便捷高效的软件产品&#xff0c;特别是在花费几万甚至十几万购买外贸软件之前&#xff0c;一定要谨慎考虑以下几个问题。 一、使用便捷…

如何选择合适的文档管理解决方案?

如何选择合适的文档管理解决方案&#xff1f; 合适的文档管理解决方案有助于保护您的数据、数字化纸质流程、保持业务连续性、满足合规性标准并为审计做好准备。 但并非所有文档管理解决方案都相同 —— 要真正实现这些好处&#xff0c;您需要一个满足某些条件的系统。 文档管…

【Linux修炼】12.深入了解系统文件

每一个不曾起舞的日子&#xff0c;都是对生命的辜负。 文件fd一. 重新谈论文件1. 共识的问题2. 重谈C语言文件操作2.1 概要2.2 C语言文件实操2.3 OS接口open的使用&#xff08;比特位标记&#xff09;2.4 写入操作2.5 追加操作2.6 只读操作二. 如何理解文件1. 提出问题2. 文件描…

Java 空指针异常的若干解决方案

Java 中任何对象都有可能为空&#xff0c;当我们调用空对象的方法时就会抛出 NullPointerException 空指针异常&#xff0c;这是一种非常常见的错误类型。我们可以使用若干种方法来避免产生这类异常&#xff0c;使得我们的代码更为健壮。本文将列举这些解决方案&#xff0c;包括…

实验十六 BGP协议基本配置

实验十六 BGP协议基本配置边界网关协议BGP(Border Gateway Protocol)是一种实现自治系统AS(Autonomous System) 之间的路由可达&#xff0c;并选择最佳路由的距离矢量路由协议。 自治系统AS (Autonomous System) AS是指在一个实体管辖下的拥有相同选路策略的IP网络。BGP网络中的…

Vue3 实现验证码倒计时

前言 倒计时的运用场景&#xff1a;获取手机验证码倒计时、获取邮箱验证码倒计时等场景&#xff0c;废话不多说&#xff0c;开始吧。 实现效果 实现代码 html&#xff08;重要部分&#xff09; <template><el-button v-if"!sms.disabled" color"#f…

通达信l2接口如何用?

在股票量化投资领域中&#xff0c;通达信l2接口如何用的知识也是要知道和了解的&#xff0c;像现在特别多的团队已经开发有多种不一样的数据接口系统&#xff0c;主要是方便大家去查询行情的时候&#xff0c;能够很快的从这些l2数据接口中产生数据&#xff0c;直观的显示数据的…

酷早报:2023年1月6日全球Web3加密行业重大资讯大汇总

2023年1月6日 星期五 【数据指标】 加密货币总市值&#xff1a;$0.82万亿 BTC市值占比&#xff1a;39.42% 恐慌贪婪指数&#xff1a;26 恐慌【今日快讯】 1、【政讯】 1.1.1、国际货币基金组织IMF&#xff1a;美国通胀尚未“转危为安” 美联储需加息到底 1.1.2、美联储布拉德&a…