用 gtk4 写 todo
终于考完了,期末考9科实在是太折磨了;发现自己很久没写文章了,上次更新还在去年,最近都在探索gtk, 就顺便写一篇记录下成果。
工具
gtk主要参考的就是官方的API reference,目前支持gtk3-4(我想也没人会去用gtk3以前的版本)的内容;其中包含 一个Widget Gallery,里面有所有当前版本的控件介绍和API。
官方的文档我认为还是很详细的,但有时候不清楚怎么使用时也还是需要去搜索用例,官方的文档一般不包含示例
IDE
和gtk有关的ide我目前找到的是Gnome Builder,介绍说是Gnome环境下的开发工具;我曾经用它编写过一些小 项目,但我认为它的补全和插件都不够完善,所以转而使用Vscode。
真要说起来,gtk的编写应该只需要一个文本编辑器,gtk4的大部分函数名都比较好记,这方面IDE也只是方便补全一些变量和函数名,提供高亮支持
构建工具
和上文说的一样,你可以选择不使用任何构建工具,使用pkg-config
查找依赖和cflags
后手动编译;但这样太过原始了,也不方便调试
Meson
Meson是gnome项目主要的编译工具,Gnome Builder也会默认安装此工具,它基于一个简单的构建配置生成build.ninja
,有点像Cmake和Makefile。
此外,在build目录下会生成compile_commands.json
,clangd可以根据此文件提供高亮和补全支持;Meson还支持增量编译,比直接重新编译更快。
Meson的文档中就包含构建gtk的示例,用dependency
提供名称,Meson就能自动查找并引入依赖
1deps = [dependency('gtk4'), dependency('libadwaita-1'), dependency('libcjson')]
libadwaita-1
在依赖中引入Adw
能让gtk应用更加现代化,符合Gnome的风格;使用方式和默认的gtk初始化相似
1g_autoptr (AdwApplication) app = NULL;
2app = adw_application_new ("org.example.Hello", G_APPLICATION_DEFAULT_FLAGS);
创建app
并用adw_application_new()
初始化;官方示例中的G_APPLICATION_FLAGS_NONE
已被弃用,用G_APPLICATION_DEFAULT_FLAGS
代替
UI绘制
我选择在ui.c
中绘制ui,将app
与home_ui
绑定
1g_signal_connect (app, "activate", G_CALLBACK (home_ui), NULL);
搜索
gtk提供了名为SearchEntry
的控件用于搜索,还有一个信号GtkSearchEntry::search-changed
,据文档说,
To make filtering appear more reactive, it is a good idea to not react to every change in the entry text immediately, but only after a short delay
也就是延迟操作输入的内容
输入处理
在获取到查询内容后,先删除原有的todo,再循环匹配所有目标类型的符合todo
1if (!strcmp (Todo_s.type[i], Todo_type)) // 目标类型
2{
3 if (strstr (Todo_s.event[i], target) != NULL) // 包含输入的todo
4 {
5 }
6}
再分别处理done
和undone
类型的todo
1if (!strcmp (Todo_type, "done"))
2{
3 gtk_check_button_set_active (GTK_CHECK_BUTTON (ckbox_todo), true); // 设置状态为true(已完成)
4 gtk_widget_set_sensitive (ckbox_todo, FALSE); // 将checkbox设为非敏感
5}
6else
7{
8 g_signal_connect (ckbox_todo, "toggled", G_CALLBACK (change_todo_to_done), NULL);
9}
样式
gtk支持用类css格式设置控件的样式,如字体大小,背景等
我也不知道怎么翻译provider更好,就当作css样式的提供者
1GtkCssProvider *provider;
2
3provider = gtk_css_provider_new ();
加载样式
1gtk_css_provider_load_from_string (provider, "checkbutton {"
2 " font-size: 22px;"
3 " background-color: #322f3b;"
4 " border-radius: 10px;"
5 "}");
6gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider),
7 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
也可以直接用gtk_widget_set_size_request()
函数调整大小
添加todo
点击添加时在中间创建Entey
和Button
,点击取消
或确定
时删除
1gtk_center_box_set_center_widget (GTK_CENTER_BOX (Cntbox), NULL);
删除控件
容器中包含删除函数,可以用gtk_widget_get_first_child (<Containers)
获取控件后用gtk_box_remove (GTK_<CONTAINER> (<Container>), widget)
删除
成品
完成后的效果如下
有点粗糙,有一些想实现的功能搁置了,后续慢慢更新吧
Gitlab: todo_gtk