TPM 程序设计基础 3-0 :GTK3 实例

前言

课设要求实现一个界面,由于老师给的 TPM 文档《TSS V1.2》是基于 C 语言的,这里我选择 GTK3 图形工具来完成。

当然也可以使用 python 自带的 Tkinter 库方便的实现,但是还要编译 .c 文件为库,再使用 python 调用同样也挺麻烦。

安装 GTK3 开发环境

实例代码

分析

创建 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” 按钮控件,控制台输出信息。

posted @ 2020-04-30 16:00  Yogile  阅读(496)  评论(0编辑  收藏  举报