14-3 编写第一个 GTK 程序

1. Hello World

        GTK 是事件驱动的工具包

        从数据处理角度,当一个事件发生时,如点击一次鼠标,所按的构件便会发出信号。所以使用 GTK 编写 hello world 时,构件需要与信号进行绑定。信号和构件的绑定函数有两种:g_signal_connect 与 g_signal_connect_swappedhttps://blog.csdn.net/shaoguangleo/article/details/6852689)。两者最大的不同点为,g_signal_connect() 函数绑定时回调函数是两个参数,主要目的是为了接收用户传入的数据g_signal_connect_swapped() 函数绑定时回调函数仅接收一个参数(构件对象),目的是为了处理构件的相关操作,而不是数据

        对于 UI 界面,不同构件之间的绑定需要注意类型的强转。窗口,容器,按钮盒,按钮之间的关系一定要理清:按钮绑定在按钮盒,按钮盒绑定在窗口。绑定时需要将被绑定对象转为容器进行绑定,例如按钮绑定在按钮盒,此时按钮盒需要强转为容器;按钮盒绑定在窗口,窗口需要强转为容器。

#include <gtk/gtk.h>

/*
 * 定义一个打印函数,在点击按钮时调用该函数
 * @param widget: 相当于GtkContainer 容器类的父类
 * @param data: 用户点击按钮时传入的数据
 */
static void print_hello(GtkWidget *widget, gpointer data){
  g_print("hello world!\n");
}

// 程序创建时调用的 activate 函数
static void activate(GtkApplication *app, gpointer user_data){

  // 1. 设置窗口
  // 为程序创建一个窗口
  GtkWidget *window = gtk_application_window_new(app);

  // 设定窗口名称,接收 GtkWindow* 类型的参数,故需要强转(GtkWidget可看作是GtkWindow的父类)
  gtk_window_set_title(GTK_WINDOW(window), "HelloWorld");

  // 设定窗口大小,接收 GtkWindow* 类型的参数
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);

  // 2. 设置窗口内部各组件
  // 设定按钮盒子,里面可以存放多个按钮,接收的参数含义为按钮横向排列
  GtkButtonBox *button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);

  // 设定按钮
  GtkButton *button = gtk_button_new_with_label("Hello World");

  // 将按钮与按钮盒绑定在一起,接收参数类型为 GtkContainer*,故此处进行强转
  gtk_container_add(GTK_CONTAINER(button_box), button);

  // 将按钮盒与窗口绑定在一起
  gtk_container_add(GTK_CONTAINER(window), button_box);

  // 3. 按钮绑定两个事件
  // 绑定按钮点击事件,点击时执行函数print_hello。执行该函数时传入数据为NULL,即print_hello函数第二个参数接收为NULL
  g_signal_connect(button, "clicked", G_CALLBACK(print_hello), NULL);

  // 绑定按钮事件,点击后自动退出该窗口,故回调函数功能为退出窗口,参数为窗口对象window
  // g_signal_connect_swapped()回调函数仅传一个参数,一个指向 GTK 对象的指针
  g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_close), window);

  // 4. 显示窗口, 传入窗口对象window
  gtk_widget_show_all(window);
}

int main(int argc, char **argv) {

  // 创建一个程序
  GtkApplication *app = gtk_application_new("com.gltzlike.clang", G_APPLICATION_FLAGS_NONE);

  // 程序创建时发出信号,进行相应的函数绑定
  // 绑定的对象是程序app,绑定信号是“activate”,绑定的函数名称为 activate,绑定时需要传入的数据为NULL
  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);

  // 运行该程序,返回状态码
  // 接收参数,其中第一个参数为GApplication *,是GtkApplication的父类;
  // 第二个和第三个参数是主程序参数(主程序运行时的参数),argc:传入的参数个数,argv:传入的参数字符串数组
  int status = g_application_run(app, argc, argv);

  // g_application_run() 函数启动后,会陷入死循环,一直监听窗口的动态(例如移动窗口,点击窗口),直到窗口退出才会返回status
  // 窗口退出后,需要释放内存
  // 调用g_object_unref()函数解引用,让app有资格释放内存
  g_object_unref(app);

  return status;
}

        最终程序运行结果如下,启动该程序,弹出窗口。

         点击 Hello World 按钮,控制台输出 "hello world!",同时窗口退出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值