TPM 程序设计基础 3-0 :GTK3 实例
前言
课设要求实现一个界面,由于老师给的 TPM 文档《TSS V1.2》是基于 C 语言的,这里我选择 GTK3 图形工具来完成。
当然也可以使用 python 自带的 Tkinter 库方便的实现,但是还要编译 .c 文件为库,再使用 python 调用同样也挺麻烦。
安装 GTK3 开发环境
实例代码
- 请下载:gtk3_exp.c
分析
创建 application
-
GTK3 中比 GTK2 增加了一个 GtkApplicaton 类,便于我们处理多窗口程序,同时有了 GtkApplication 我们也更容易创建灵活,易用,界面美观的应用程序。
具体每步代码不深入描述。
-
主要在
int main(xxx, xxx)
函数中。//申明创建一个 GtkApplicatin对象名为app GtkApplication *app; //用于拿到app 运行结束后的返回值 int app_status; //创建一个application app = gtk_application_new("org.gtk.exmple" , G_APPLICATION_FLAGS_NONE); //连接信号,初始化app时,调用 activate 函数 g_signal_connect(app , "activate" , G_CALLBACK(activate) , NULL); //运行app app_status = g_application_run(G_APPLICATION(app) , argc , argv); //销毁app g_object_unref(app);
-
这时就出现了 第一个知识点 :
g_signal_connect()
函数。
创建 application 回调函数
g_signal_connect()
函数对于回调函数有一定的格式。
-
格式:
static void <函数名> (GtkWidget *button , gpointer data) { ...... }
-
示例中的
activate()
作用:创建窗口、容器、控件。一般来说,创建窗口、容器、控件是分布在不同的函数中的,实例代码比较简单,就写在一块了。
创建窗口
-
看注释一目了然,实例代码:
//申明一个窗口 GtkWidget *win; //为app创建一个窗口 win = gtk_application_window_new(app); //设置窗口的标题 gtk_window_set_title(GTK_WINDOW(win) , "Button test"); //设置窗口默认大小为长宽各200像素 gtk_window_set_default_size(GTK_WINDOW(win) , 200 , 200); ...... //显示window及其所有控件 gtk_widget_show_all(win);
创建容器
-
实例代码中创建的是水平容器.
- 基于水平容器的控件,由库中程序自动水平调整。
//申明一个盒容器,用于容纳按钮,控制大小 GtkWidget *button_box; //创建一个盒容器,并设置水平放置 button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); //将盒容器包含进window中 gtk_container_add(GTK_CONTAINER(win) , button_box);
-
课设中创建的是固定容器.
- 基于固定容器的控件,需手动设置控件位置、宽度、高度。
//申明一个盒容器,用于容纳按钮,控制大小 GtkWidget *fixed_box; //创建一个固定容器 fixed_box = gtk_fixed_new(); //将容器包含进window中 gtk_container_add(GTK_CONTAINER(win) , fixed_box);
创建控件
-
基于水平容器的控件。
//申明一个按钮 GtkWidget *button; //创建一个按钮,并带有“My button” 的标签 button = gtk_button_new_with_label("My button"); //连接信号,让点击按钮后,便调用 print_msg 函数 g_signal_connect(button , "clicked" , G_CALLBACK( print_msg ) , NULL); //将按钮放入盒容器中 gtk_container_add(GTK_CONTAINER(button_box) , button);
-
基于固定容器的控件。
课设程序中专门为主窗口中的控件建立了一个函数:
static void controller(GtkWidget *fixed_box)
。static void controller(GtkWidget *fixed_box) { //申明一个按钮 GtkWidget *button_pcr_get; //创建一个按钮,并带有“读取 PCR” 的标签 button_pcr_get = gtk_button_new_with_label("读取 PCR"); //按钮添加到固定布局 gtk_fixed_put(GTK_FIXED(fixed_box), button_pcr_get, 100, 50); //设置控件的大小 gtk_widget_set_size_request(button_pcr_get, 100, 50); ...... }
-
对比:
-
基于水平容器的控件没有函数:
-
gtk_fixed_put()
:将按钮添加到固定布局。但是控件已经由后台程序自动对齐显示,更方便。
-
-
基于固定容器的控件没有函数:
-
gtk_container_add()
:将按钮放入盒容器中。但是固定容器的
gtk_fixed_put()
函数已经将控件放入盒容器中了,更自由。
-
-
-
调用回调函数没有区别。
//连接信号,让点击 按钮 后,便调用 print_msg 函数 g_signal_connect(button , "clicked" , G_CALLBACK( print_msg ) , NULL);
创建 按钮控件 回调函数
//点击按钮后被调用的函数,用于输出hello,world
static void print_msg (GtkWidget *button , gpointer data)
{
printf("Hello , world!\n");
}
gpointer data
值为NULL
。
编译、运行
-
编译。
gcc src/gtk3_exp.c -o out/gtk3_exp.out `pkg-config --cflags --libs gtk+-3.0`
-
运行。
./out/gtk3_exp.out
- 点击 “My button” 按钮控件,控制台输出信息。