六、Gtk4-Widgets (3)

news2024/11/19 15:29:51

1 Open 信号

1.1 G_APPLICATION_HANDLES_OPEN flag

在上一节中,我们使用GtkTextView、GtkTextBuffer和GtkScrolledWindow创建了一个非常简单的编辑器。我们将为程序添加文件读取功能,并将其改进为文件查看器。

要给出文件名,最简单的方法是使用命令行参数。

$ ./a.out filename

该程序将打开文件并将其内容插入GtkTextBuffer。

为此,我们需要知道GtkApplication(或GApplication)如何识别参数。这在GIO API参考-应用程序中描述。

当创建GtkApplication时,一个标志(GApplicationFlags)作为参数给出。

GtkApplication *
gtk_application_new (const gchar *application_id, GApplicationFlags flags);

本教程只解释两个标志,G_APPLICATION_DEFAULT_FLAGSG_APPLICATION_HANDLES_OPEN。(在GIO version2.73.3之前使用了G_APPLICATION_FLAGS_NONE而不是G_APPLICATION_DEFAULT_FLAGS (GLib 2.73.3 5/Aug/2022)。有些GTK 4应用程序仍然使用G_APPLICATION_FLAGS_NONE。但现在已弃用,建议使用G_APPLICATION_DEFAULT_FLAGS。)如果你想处理命令行参数,G_APPLICATION_HANDLES_COMMAND_LINE标志就是你所需要的。

有关更多信息,请参阅GIO API Reference——ApplicationFlags和GIO API Reference——g_application_run。

我们已经使用了G_APPLICATION_DEFAULT_FLAGS,因为它是最简单的选项,并且不允许任何命令行参数。如果你提供了参数,就会发生错误。

第二简单的选项是G_APPLICATION_HANDLES_OPEN标志。它允许参数,但只允许文件。应用程序假定所有参数都是文件名。

app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);

1.2 open 信号

在G_APPLICATION_HANDLES_OPEN标志提供给应用程序时,有两个信号可用。

  • activate signal——这个信号在没有参数时发出。
  • open signal——当至少有一个参数时,该信号被触发。

“open”信号的处理程序定义如下。

void
open (
  GApplication* self,
  gpointer files,
  gint n_files,
  gchar* hint,
  gpointer user_data
)

参数有:

  • self——应用程序实例(通常是GtkApplication)
  • files——一个gfile数组。[array length=n_files][element-type GFile]
  • n_files——文件元素的数目
  • hint——由调用实例提供的提示(通常可以忽略)
  • user_data——连接信号处理程序时的用户数据集。

2 开发一个文件查看器

2.1 什么是一个文件查看器

文件查看器是一个显示文本文件的程序。我们的文件查看器将按如下方式工作。

  • 当给出参数时,它将第一个参数识别为文件名并打开它。
  • 第二个参数和后面的参数会被忽略。
  • 如果没有参数,它会显示一条错误消息并退出。
  • 如果它成功打开文件,它读取文件的内容,将它们插入 GtkTextBuffer并显示窗口。
  • 如果打开文件失败,它会显示一个错误消息并退出。

程序如下所示。

 1 #include <gtk/gtk.h>
 2 
 3 static void
 4 app_activate (GApplication *app) {
 5   g_printerr ("You need a filename argument.\n");
 6 }
 7 
 8 static void
 9 app_open (GApplication *app, GFile ** files, int n_files, char *hint) {
10   GtkWidget *win;
11   GtkWidget *scr;
12   GtkWidget *tv;
13   GtkTextBuffer *tb;
14   char *contents;
15   gsize length;
16   char *filename;
17 
18   win = gtk_application_window_new (GTK_APPLICATION (app));
19   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
20 
21   scr = gtk_scrolled_window_new ();
22   gtk_window_set_child (GTK_WINDOW (win), scr);
23 
24   tv = gtk_text_view_new ();
25   tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
26   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
27   gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
28   gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
29 
30   if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) {
31     gtk_text_buffer_set_text (tb, contents, length);
32     g_free (contents);
33     if ((filename = g_file_get_basename (files[0])) != NULL) {
34       gtk_window_set_title (GTK_WINDOW (win), filename);
35       g_free (filename);
36     }
37     gtk_window_present (GTK_WINDOW (win));
38   } else {
39     if ((filename = g_file_get_path (files[0])) != NULL) {
40       g_printerr ("No such file: %s.\n", filename);
41       g_free (filename);
42     } else
43       g_printerr ("File can't be opened.\n");
44     gtk_window_destroy (GTK_WINDOW (win));
45   }
46 }
47 
48 int
49 main (int argc, char **argv) {
50   GtkApplication *app;
51   int stat;
52 
53   app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
54   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
55   g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);
56   stat = g_application_run (G_APPLICATION (app), argc, argv);
57   g_object_unref (app);
58   return stat;
59 }

保存以上代码到tfv3.c,并且编译和运行它。

$ comp tfv3
$ ./a.out tfv3.c

在这里插入图片描述
与前一个版本相比,函数main只有两个变化。

  • G_APPLICATION_DEFAULT_FLAGS替换为 -G_APPLICATION_HANDLES_OPEN
  • 添加g_signal_connect (app, “open”, G_CALLBACK (app_open), NULL)。

在将标志G_APPLICATION_HANDLES_OPEN传递给gtk_application_new函数时,应用程序的行为如下:

  • 如果应用程序在没有命令行参数的情况下运行,它被激活时会发出“activate”信号。
  • 如果应用程序以命令行参数运行,则在激活时发出“open”信号。

处理程序app_activate变得非常简单。它只是输出错误消息并返回给调用者。然后应用程序立即退出,因为没有创建窗口。

主要工作在处理程序app_open中完成。

创建GtkApplicationWindow, GtkScrolledWindow, GtkTextView和GtkTextBuffer,并将它们连接在一起
在GtktextView中设置wrap模式为GTK_WRAP_WORD_CHAR
将GtkTextView设置为不可编辑,因为程序不是编辑器,而是查看器
读取文件并将文本插入GtkTextBuffer(稍后会解释)。
如果文件没有打开,输出一个错误消息并销毁窗口。这会让应用退出。

下面是程序读取文件的部分。

if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) {
  gtk_text_buffer_set_text (tb, contents, length);
  g_free (contents);
  if ((filename = g_file_get_basename (files[0])) != NULL) {
    gtk_window_set_title (GTK_WINDOW (win), filename);
    g_free (filename);
  }
  gtk_widget_show (win);
} else {
  if ((filename = g_file_get_path (files[0])) != NULL) {
    g_printerr ("No such file: %s.\n", filename);
    g_free (filename);
  } else
    g_printerr ("File can't be opened.\n");
  gtk_window_destroy (GTK_WINDOW (win));
}

函数g_file_load_contents将文件内容加载到一个临时缓冲区中,该缓冲区是自动分配的,并将内容设置为指向该缓冲区。将缓冲区的长度赋值给length。如果文件内容加载成功,它返回TRUE;如果发生错误,则返回FALSE。如果想了解有关g_file_load_contents的详细信息,请参见g file load contents。

如果成功读取文件,则将内容插入到GtkTextBuffer中,释放由内容指向的临时缓冲区,设置窗口标题,释放由文件名指向的内存,然后显示窗口。如果失败,则输出错误消息并销毁窗口,最后让程序退出。

3 GtkNotebook

GtkNotebook是一个容器部件,可以包含多个带有标签的构件。它一次只显示一个子构建。当单击其标签时,将显示另一个子构件。
在这里插入图片描述大多数更改都发生在app_open函数中。以下项目左侧的数字是源代码中的行号。

  • 11-13:定义了变量nb、lab和nbp。它们分别指向GtkNotebook、GtkLabel和GtkNotebookPage。
  • 23:窗口的标题设置为"file viewer"。
  • 24:窗口默认大小为600x400。
  • 26-27创建了gtnotebook,并将其作为子构件插入到GtkApplicationWindow中。
  • 29-58 for循环。变量files[i]指向第i个GFile,它是由GtkApplication根据第i个命令行参数创建的。
  • 31-36 创建GtkScrollledWindow、GtkTextView。GtkTextBuffer是从GtkTextView获得的。GtkTextView作为子构件连接到GtkScrolledWindow。
  • 38-39将文件的内容插入到GtkTextBuffer中,并释放内容指向的内存。
  • 40-42:如果文件名来自GFile,则使用该文件名创建GtkLabel。字符串filename被释放。
  • 43-44:如果获取文件名失败,则创建空字符串GtkLabel。
  • 45-46:将GtkScrolledWindow作为子构件附加到GtkNotebook。并将GtkLabel设置为子构件的选项卡。同时,GtkNoteBookPage会被自动创建。函数gtk_notebook_get_page返回子构件(GtkScrolledWindow)页面的GtkNotebookPage。
    47: GtkNotebookPage具有“tab-expand”属性。如果设置为TRUE,选项卡就会尽可能地水平展开。如果为FALSE,则选项卡的宽度由标签的大小决定。g_object_set是一个设置对象属性的通用函数。参见GObject API参考——g_object_set。
    48-50:如果读取文件失败,从GFile中取了文件名,则显示“No such file”。文件名被释放。
    51-52:如果filename为NULL,则显示“No valid file is given”。
    54—57:如果至少存在一个页面,则显示该窗口。否则,窗口将被销毁,应用程序将退出。

参考:Gtk4 tutorial Widgets (3)

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

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

相关文章

(软考)系统架构师大纲

考试要求&#xff1a; 掌握计算机硬软件与网络的基础知识;熟悉信息系统开发过程;理解信息系统开发标准、常用信息技术标准;熟悉主流的中间件和应用服务器平台;掌握软件系统建模、系统架构设计基本技术;熟练掌握信息安全技术、安全策略、安全管理知识;了解信息化、信息技术有关…

使用Vite搭建vue3+TS项目

vite简介 vite 是一个基于 Vue3 单文件组件的非打包开发服务器&#xff0c;它具有快速的冷启动&#xff0c;不需要等待打包操作&#xff1b;并且官网说是下一代的前端构建工具。 初始化项目 npm init vitelatest1.输入项目名称 2.选择Vue 3.选择TS 4.启动项目 5.项目启…

【阶段三】Python机器学习07篇:模型评估函数介绍(回归模型)

本篇的思维导图: 模型评估函数介绍(回归模型) 绝对误差与相对误差: 设Y表示实际值, 表示预测值,则称E为绝对误差(Absolute Error),计算公式如式所示: e为相对误差(Relative Error),计算公式如式所示:

Maven怎么写本地仓库没有的架包坐标

什么是jar包的坐标&#xff1f; 当我们使用Maven开发一个项目时&#xff0c;需要向项目中导入很多个jar包&#xff0c;这些jar包不需要我们自己一个个的导入&#xff0c;只需要在创建的项目中的pom.xml文件中写上需要的jar包的坐标&#xff0c;Maven就会去本地仓库找有没有这个…

黑马学ElasticSearch(一)

目录&#xff1a; &#xff08;1&#xff09;初识ES-什么是elasticsearch &#xff08;2&#xff09;初识ES-倒排索引 &#xff08;3&#xff09;ES与MySQL的概念对比 &#xff08;4&#xff09;安装ES &#xff08;1&#xff09;初识ES-什么是elasticseach 随着业务的发…

MYSQL8.0+远程连接|主从复制配置|各种错误(吐血整理)

目录 环境介绍 主机/从机文件配置 主机部分 从机部分 连接测试 报错踩坑|解决办法 写在前面&#xff1a;最近在做项目优化&#xff0c;看完黑马的mysql的主从复制后&#xff0c;准备着手来练练&#xff0c;没想到这入坑就是三四天的错&#xff0c;心情烦躁。如今已解决&a…

SpringCloud笔记 - Day1 概念注册中心负载均衡

https://www.bilibili.com/video/BV1LQ4y127n4 1. 微服务导学 异步通信可以大大提高服务的并发。 服务的异常定位&#xff1a; 分布式日志服务系统监控和链路追踪 自动化部署&#xff1a;Jenkins——docker——k8s——RANCHER 持续集成 2. 微服务导学2 微服务治理、异步通…

【EHub_tx1_tx2_E100】Ubuntu18.04 + ROS_ Melodic + RS-LiDAR-16 激光雷达测试

简介&#xff1a;介绍 RS-LiDAR-16 16线激光雷达 在EHub_tx1_tx2_E100载板&#xff0c;TX1核心模块环境&#xff08;Ubuntu18.04&#xff09;下测试ROS驱动&#xff0c;如何打开使用RVIZ 查看点云数据&#xff0c;本文的前提条件是你的TX1里已经安装了ROS版本&#xff1a;Melo…

类和对象2

static关键字 1.静态变量或方法不属于对象&#xff0c;但依赖类。 2.静态变量是全局变量&#xff0c;生命周期从类被加载后一直到程序结束 3.静态变量内存只存一份&#xff0c;在静态方法区存储&#xff08;静态方法区&#xff1a;静态变量&#xff0c;类信息&#xff08;方法…

Odoo 16 企业版手册 - 库存管理之仓库管理

仓库管理 仓库管理是公司库存运营中的重要活动之一。为了使库存运营和调拨的顺利运作&#xff0c;公司的仓库应该得到适当的管理和监控。Odoo&#xff0c;作为一名优秀的库存管理助理&#xff0c;可以为您提供有效管理公司仓库的专用平台。Odoo提供的工具可以帮助您同时管理多个…

解决Tinkphp的success跳转“使用路由别名后模块和控制器访问不了”问题

遇到的问题&#xff1a;我的thinkphp5网站添加了以下路由别名&#xff1a;Route::alias([ index>index/index, ]);使用http://域名/Index/user/password.html访问正常但使用http://域名/index/user/password.html就访问失败使用$this->success(修改密码成功);进行提示跳转…

【MySQL】MySQL面试题八股文详解——事务篇

【MySQL】MySQL面试题八股文详解——事务篇 1&#xff1a;什么是数据库事务&#xff1f; 一言蔽之&#xff0c;事务是逻辑上的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行。 是数据库操作的最小工作单元&#xff0c;是作为单个逻辑工作单元执行的一系列操作&…

C语言经典编程题 --- 打印菱形

目录 一、题目描述 二、普通解法 三、曼哈顿距离解法 一、题目描述 输入一个奇数 n&#xff0c;输出一个由 * 构成的 n 阶实心菱形 输入格式&#xff1a;一个奇数 n。 输出格式&#xff1a;输出一个由 * 构成的 n 阶实心菱形。 输入样例&#xff1a;5输出样例&#xff1…

【操作系统】生产环境消失的进程如何排查

文章目录1.生产环境问题描述2.Linux软件环境准备3.编译运行程序&#xff0c;分析现象4.进程消失原因分析5.生产类似进程消失的案例6.如何通过日志查看消失进程1.生产环境问题描述 一台机器上的某个进程直接就消失了&#xff0c;别的机器上的服务都正常跑着&#xff0c;怎么排查…

AI城管占道经营识别检测算法 yolo

AI城管占道经营识别检测算法通过yolopython深度学习训练框架模型对道路街区小摊贩占道经营违规摆摊行为进行检测&#xff0c;检测有出店经营占道经营违规摆摊情况&#xff0c;yolopython深度学习训练框架模型会立即抓拍存档。我们使用YOLO(你只看一次)算法进行对象检测。YOLO是…

重学ElasticSearch (ES) :ELK搭建SpringBoot日志实时分析系统

一、概述 在一个大型的分布式架构的项目里&#xff0c;不同的服务模块部署在不同的服务器上&#xff0c;如果想要定位问题&#xff0c;可能需要去不同的服务器上查看不同服务的日志。 那么&#xff0c;ELK可以很方便的把日志集成到一起&#xff0c;无须再去各个服务器上的日志中…

Python自带的常数scipy.constants

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】Python自带的常数scipy.constants[太阳]选择题以下python代码结果错误的一项是?from scipy import constants print(【圆周率constants.pi】,constants.pi)print(【时间单位constants.minute】…

[实例讲解]计算机处理任务的方法和原理--线程

[实例讲解]计算机处理任务的方法和原理 文章目录[实例讲解]计算机处理任务的方法和原理情景一 所有的事情自己做情景二 找人去帮忙处理打印情景三 分别找人处理编码和打印情景四 不特定指定人去帮忙结束语在学习和工作中&#xff0c;我们自己都需要做很多的事情&#xff0c;事情…

【机器学习】匈牙利和KM匹配个人理解

基础知识 二分图 【定义】图论中的一种特殊模型。若能将无向图G(V,E)的顶点V划分为两个交集为空的顶点集&#xff0c;并且任意边的两个端点都分属于两个集合&#xff0c;则称图G为一个为二分图。 【解释】一张图要是二分图&#xff0c;需要满足以下几个要求&#xff1a; &a…

PS 矩形选区工具(2)模式快捷键 选区比例调整 颜色填充

本文为PS 矩形选区工具(1)基本用法 生成图层 选区方式演示讲解的续文 拉出选区后 用鼠标拖动选区 是可以拖动选区位置的 拉出一块选区是 按住键盘 Shift键 就可以用鼠标再拖出一块选区 加选区快捷键 按住 Shift 减选区 按住键盘 Alt 键 用鼠标拖出不要的选区位置即可 减选…