当前位置: 首页 > news >正文

gtk4学习

前几天学习GDB,下载了张老师写的一个GTK图形程序,在我ubuntu机器上运行不了,界面直接死掉了。所以今天准备简单学习一下gtk

背景:

linux最常用的两种X客户端是KDE和GNOME.
KDE指的是K桌面环境(K Desktop Environment)​,是一种运行于UNIX以及Linux, FreeBSD等类UNIX操作系统上面的自由图形工作环境。
KDE是一个综合的桌面环境,建立在XFree86和QT的基础上.
GNOME桌面系统使用C语言编程.
Linux系统下常用的图形界面开发环境有Qt和GTK两种.GTK(GIMP Toolkit)是一套跨多种平台的图形工具包,完全按照LGPL许可协议发布。
yum install gtk+
现在已经是gtk4了,安装方法:
sudo apt-get install libgtk-4-1 libgtk-4-dev gtk-4-examples
这样就可以使用gtk4了。

搜索了一下,看官方文档靠谱:

Gtk – 4.0: Getting Started with GTK

目录

第一个例子:生成一个Windows窗口。

带按钮的例子

排列


第一个例子:生成一个Windows窗口。

#include <gtk/gtk.h>static void
activate (GtkApplication* app,gpointer        user_data)
{GtkWidget *window;window = gtk_application_window_new (app);gtk_window_set_title (GTK_WINDOW (window), "Window");gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);gtk_window_present (GTK_WINDOW (window));
}int
main (int    argc,char **argv)
{GtkApplication *app;int status;app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);status = g_application_run (G_APPLICATION (app), argc, argv);g_object_unref (app);return status;
}

编译:

$( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )

编译不过,参考:The GTK Project - A free and open-source cross-platform widget toolkit

sudo apt-get install libgtk-4-1 libgtk-4-dev gtk-4-examples

再编译就通过了,也可以运行。

下面解析一下这个小程序:

#include <gtk/gtk.h>
All GTK applications will, of course, include gtk/gtk.h, 
which declares functions, types and macros required by GTK applications.

GtkApplication *app;
In a GTK application, the purpose of the main() function is to create a GtkApplication object and run it. 
In this example a GtkApplication pointer named app is declared and then initialized using gtk_application_new().

app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
When creating a GtkApplication, 
you need to pick an application identifier (a name) and pass it to gtk_application_new() as parameter. 
For this example org.gtk.example is used. For choosing an identifier for your application, see this guide. 
Lastly, gtk_application_new() takes GApplicationFlags as input for your application, 
if your application would have special needs.

g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);

Next the activate signal is connected to the activate() function above the main() function. 
The activate signal will be emitted when your application is launched with g_application_run() on the line below. 
The g_application_run() call also takes as arguments the command line arguments (the argc count and the argv string array). 
Your application can override the command line handling, e.g. to open files passed on the commandline.

activate (GtkApplication* app, gpointer        user_data)
GtkWidget *window;
window = gtk_application_window_new (app);

Within g_application_run() the activate signal is sent and we then proceed into the activate() function of the application. 
This is where we construct our GTK window, so that a window is shown when the application is launched. 
The call to gtk_application_window_new() will create a new GtkApplicationWindow and store it inside the window pointer. 
The window will have a frame, a title bar, and window controls depending on the platform.

gtk_window_set_title (GTK_WINDOW (window), "Window");
A window title is set using gtk_window_set_title(). 
This function takes a GtkWindow pointer and a string as input. 
As our window pointer is a GtkWidget pointer, we need to cast it to GtkWindow; 
instead of casting window via a typical C cast like (GtkWindow*), 
window can be cast using the macro GTK_WINDOW(). 
GTK_WINDOW() will check if the pointer is an instance of the GtkWindow class, before casting, and emit a warning if the check fails. 
More information about this convention can be found in the GObject documentation.

gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_window_present (GTK_WINDOW (window));

Finally the window size is set using gtk_window_set_default_size() and the window is then shown by GTK via gtk_widget_show().

g_object_unref (app);
When you close the window, by (for example) pressing the X button, 
the g_application_run() call returns with a number which is saved inside an integer variable named status. 
Afterwards, the GtkApplication object is freed from memory with g_object_unref(). 
Finally the status integer is returned and the application exits.

带按钮的例子

#include <gtk/gtk.h>static void
print_hello (GtkWidget *widget,gpointer   data)
{g_print ("Hello World\n");
}static void
activate (GtkApplication *app,gpointer        user_data)
{GtkWidget *window;GtkWidget *button;GtkWidget *box;window = gtk_application_window_new (app);gtk_window_set_title (GTK_WINDOW (window), "Window");gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);gtk_widget_set_halign (box, GTK_ALIGN_CENTER);gtk_widget_set_valign (box, GTK_ALIGN_CENTER);gtk_window_set_child (GTK_WINDOW (window), box);button = gtk_button_new_with_label ("Hello World");g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);gtk_box_append (GTK_BOX (box), button);gtk_window_present (GTK_WINDOW (window));
}int
main (int    argc,char **argv)
{GtkApplication *app;int status;app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);status = g_application_run (G_APPLICATION (app), argc, argv);g_object_unref (app);return status;
}

GtkWidget *box;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);

The GtkBox widget is created with gtk_box_new(), which takes a GtkOrientation enumeration value as parameter. 
The buttons which this box will contain can either be laid out horizontally or vertically. 
This does not matter in this particular case, as we are dealing with only one button. 
After initializing box with the newly created GtkBox, 
the code adds the box widget to the window widget using gtk_window_set_child().

button = gtk_button_new_with_label ("Hello World");
gtk_box_append (GTK_BOX (box), button);

Next the button variable is initialized in similar manner. gtk_button_new_with_label() is called which returns a GtkButton to be stored in button. 
Afterwards button is added to our box.

g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
Using g_signal_connect(), the button is connected to a function in our app called print_hello(), 
so that when the button is clicked, GTK will call this function. 
As the print_hello() function does not use any data as input, NULL is passed to it. 
print_hello() calls g_print() with the string “Hello World” which will print Hello World in a terminal if the GTK application was started from one.

g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);  --可以传参数
After connecting print_hello(), 
another signal is connected to the “clicked” state of the button using g_signal_connect_swapped(). 
This functions is similar to a g_signal_connect(), with the difference lying in how the callback function is treated; 
g_signal_connect_swapped() allows you to specify what the callback function should take as parameter by letting you pass it as data. 
In this case the function being called back is gtk_window_destroy() and the window pointer is passed to it. 
This has the effect that when the button is clicked, the whole GTK window is destroyed. 
In contrast if a normal g_signal_connect() were used to connect the “clicked” signal with gtk_window_destroy(), 
then the function would be called on button (which would not go well, since the function expects a GtkWindow as argument).
 

排列

多个widget需要有一定的排列规则。

#include <gtk/gtk.h>static void
print_hello (GtkWidget *widget,gpointer   data)
{g_print ("Hello World\n");
}static void
activate (GtkApplication *app,gpointer        user_data)
{GtkWidget *window;GtkWidget *grid;GtkWidget *button;/* create a new window, and set its title */window = gtk_application_window_new (app);gtk_window_set_title (GTK_WINDOW (window), "Window");/* Here we construct the container that is going pack our buttons */grid = gtk_grid_new ();/* Pack the container in the window */gtk_window_set_child (GTK_WINDOW (window), grid);button = gtk_button_new_with_label ("Button 1");g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);/* Place the first button in the grid cell (0, 0), and make it fill* just 1 cell horizontally and vertically (ie no spanning)*/gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);button = gtk_button_new_with_label ("Button 2");g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);/* Place the second button in the grid cell (1, 0), and make it fill* just 1 cell horizontally and vertically (ie no spanning)*/gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);button = gtk_button_new_with_label ("Quit");g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);/* Place the Quit button in the grid cell (0, 1), and make it* span 2 columns.*/gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);gtk_window_present (GTK_WINDOW (window));
}int
main (int    argc,char **argv)
{GtkApplication *app;int status;app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);status = g_application_run (G_APPLICATION (app), argc, argv);g_object_unref (app);return status;
}

相关文章:

  • SPI驱动学习七(SPI_Slave_Mode驱动程序框架)
  • AI驱动的Java开发框架:Spring AI Alibaba实战部署教程
  • C++之STL—常用排序算法
  • TDSQL-C电商可视化,重塑电商决策新纪元
  • IoT网关的主要功能有哪些?天拓四方
  • Hive优化高频面试题
  • Centos Stream 9根目录扩容
  • 【MySQL】函数及存储过程
  • GUI-工具栏(页签)和选择网格
  • leetcode621. 任务调度器
  • C++【类和对象】(构造函数与析构函数)
  • 全球200多个国财政数据(1991-2023年)
  • 学习之什么是装饰器
  • Java | Leetcode Java题解之第435题无重叠区间
  • 5.3 克拉默法则、逆矩阵和体积
  • [NodeJS] 关于Buffer
  • es的写入过程
  • JS实现简单的MVC模式开发小游戏
  • MySQL的数据类型
  • Terraform入门 - 1. 安装Terraform
  • ⭐ Unity + OpenCV 实现实时图像识别与叠加效果
  • 从零开始的无人驾驶 1
  • 大整数乘法-表格法
  • 动态规划入门(以爬楼梯为例)
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 网页视频流m3u8/ts视频下载
  • 译米田引理
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • ​ssh免密码登录设置及问题总结
  • ​力扣解法汇总946-验证栈序列
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (23)mysql中mysqldump备份数据库
  • (floyd+补集) poj 3275
  • (六)c52学习之旅-独立按键
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (篇九)MySQL常用内置函数
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (原创)可支持最大高度的NestedScrollView
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .ai域名是什么后缀?
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET 药厂业务系统 CPU爆高分析
  • .net对接阿里云CSB服务
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • [ 数据结构 - C++] AVL树原理及实现
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [145] 二叉树的后序遍历 js
  • [AWS]CodeCommit的创建与使用
  • [bzoj1324]Exca王者之剑_最小割
  • [C#]winform制作仪表盘好用的表盘控件和使用方法
  • [Codeforces] combinatorics (R1600) Part.2
  • [Codeforces1137D]Cooperative Game
  • [Debugger]调试Arm设备