zoukankan      html  css  js  c++  java
  • Linux 下从头再走 GTK+-3.0 (六)

      在 GTK3 中增加了一个 GtkApplicaton 类,便于我们处理多窗口程序,同时有了 GtkApplication 我们也更容易创建灵活,易用,界面美观的应用程序。

    在前面的几个例子中,演示了如何利用 GtkApplication 直接创建单个窗口,并知道了在哪里设计我们的 UI 。以及简单尝试了 GtkBuilder 。

    接下来,我们走进 GtkApplication 。采用面向对象的设计方式设计我们的应用。

    我们想要封装一个 MyApp 和 MyAppWindow , 它继承了 GtkApplcation 和 GtkApplicationWindow。

    首先需要创建如下几个文件:

    main.c : 主函数在此文件。

    myapp.c mypp.h : 封装的 MyApp

    myappwindow.c myappwindow.h : 封装的 MyAppWindow

      采用这样的设计方式,主函数里面只需要一句话,main.c 内容如下:

    #include <gtk/gtk.h>
    
    #include "myapp.h"
    
    
    int main(int argc , char *argv[])
    {
        //my_app_new() 是我们封装好的,创建一个 MyApp 的接口
        return g_application_run ( G_APPLICATION ( my_app_new() ) , argc , argv );
    }

      接下来是 myapp.c

    #include <gtk/gtk.h>
    
    #include "myapp.h"
    #include "myappwindow.h"      //使用到我们封装的 MyAppWindow 提供的接口
    
    //利用C语言结构,创建 MyApp 类型, 其父类型为 GtkApplication
    struct _MyApp
    {
        GtkApplication parent;
    };
    
    //同样定义 MyAppClass 类
    struct _MyAppClass
    {
        GtkApplicationClass parent_class;
    };
    
    //利用G_DEFINE_TYPE 宏,注册定义 MyApp 类型 , 对应参数分别代表:类型名 , 小写类型名(用下划线分隔) , 父类型
    G_DEFINE_TYPE ( MyApp , my_app , GTK_TYPE_APPLICATION );
    
    //my_app初始化函数原型
    static void my_app_init (MyApp *app)
    {
    
    }
    //my_app activate 信号原型 , 相当于之前几节我们手动链接的 activate 函数
    static void my_app_activate (GApplication *app)
    {
        MyAppWindow *win;
    
        //因此在这里面创建窗口,用我们封装好的 MyAppWindow
        win = my_app_window_new ( MY_APP(app) );
        //将窗口放在前台 , 自动调用 gtk_widget_show_all()
        gtk_window_present (GTK_WINDOW(win));
    }
    //处理命令行参数的函数原型 
    static void my_app_open (GApplication *app , 
                             GFile       **files ,
                             gint          n_files , 
                             const gchar  *hint)
    {
        GList *windows;
        MyAppWindow *win;
        int i;
    
        windows = gtk_application_get_windows ( GTK_APPLICATION(app) );
        if(windows)
            win = MY_APP_WINDOW( windows->data );
        else
            win = my_app_window_new ( MY_APP(app) );
    
        for(i = 0; i < n_files; i++)
            my_app_window_open ( win , files[i] );
    
        gtk_window_present ( GTK_WINDOW(win) );
    }
    
    //MyApp 类的初始化函数,在这里面即可复写MyApp类继承GtkAppliation类的默认信号处理函数。
    static void my_app_class_init ( MyAppClass *class)
    {
        //将activate信号和open信号处理函数改为我们写的
        G_APPLICATION_CLASS (class) ->activate = my_app_activate;
        G_APPLICATION_CLASS (class) ->open     = my_app_open;
    }
    
    //这是向外提供的接口,不用加 static 修饰。 
    MyApp *my_app_new (void)
    {
        //按照我们创建的类型创建一个 MyApp
        return g_object_new ( MY_APP_TYPE , 
                              "application-id" ,
                              "org.gtk.myapp" , 
                              "flags" , 
                              G_APPLICATION_HANDLES_OPEN , 
                              NULL);
    }

      myapp.h 内容如下:

    #ifndef _My_App_H
    #define _My_App_H
    
    #include <gtk/gtk.h>
    
    
    //my_app_get_type() 这些函数,我们虽然没写,但是在注册定义 MyApp 类型的时候根据填写的 my_app 会自动生成。
    #define MY_APP_TYPE ( my_app_get_type () )
    #define MY_APP(obj) ( G_TYPE_CHECK_INSTANCE_CAST( (obj) , MY_APP_TYPE , MyApp) )
    
    typedef struct _MyApp       MyApp;
    typedef struct _MyAppClass  MyAppClass;
    
    
    //在 myapp.c 中的其他函数属于私有,暂时不需要向外提供。
    GType  my_app_get_type  (void);
    MyApp *my_app_new       (void);
    
    
    #endif // _My_App_

      下面封装MyAppWindow类型的方式和上面一样,如下是 myappwindow.c

    #include <gtk/gtk.h>
    
    #include "myapp.h"
    #include "myappwindow.h"
    
    struct _MyAppWindow
    {
        GtkApplicationWindow parent;
    };
    
    struct _MyAppWindowClass
    {
        GtkApplicationWindowClass parent_class;
    };
    
    G_DEFINE_TYPE ( MyAppWindow , my_app_window , GTK_TYPE_APPLICATION_WINDOW);
    
    static void my_app_window_init ( MyAppWindow *app)
    {
    
    }
    
    static void my_app_window_class_init ( MyAppWindowClass *class)
    {
        
    }
    
    MyAppWindow *my_app_window_new (MyApp *app)
    {
        return g_object_new ( MY_APP_WINDOW_TYPE , 
                              "application" , 
                              app , 
                              NULL);    
    }
    
    void my_app_window_open ( MyAppWindow *win , GFile *file)
    {
    
    }

      以及 myappwindow.h

    #ifndef _My_App_Window_H
    #define _My_App_Window_H
    
    #include <gtk/gtk.h>
    #include "myapp.h"
    
    #define MY_APP_WINDOW_TYPE   (my_app_window_get_type())
    #define MY_APP_WINDOW(obj)   (G_TYPE_CHECK_INSTANCE_CAST( (obj) , MY_APP_WINDOW_TYPE , MyAppWindow) )
    
    typedef struct _MyAppWindow            MyAppWindow;
    typedef struct _MyAppWindowClass       MyAppWindowClass;
    
    GType          my_app_window_get_type   (void);
    MyAppWindow   *my_app_window_new        (MyApp *app);
    void           my_app_window_open       (MyAppWindow *win , GFile *file);
    
    #endif //_My_App_Window_

      编译并运行:

    gcc main.c myapp.c myappwindow.c  `pkg-config --cflags --libs gtk+-3.0` -Wall
    ./a.out

      运行结果如下:

  • 相关阅读:
    openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)
    LINQ to SQL活学活用(1):这要打破旧观念
    【安卓】乾坤大罗移,将容器触摸事件传至还有一容器、!
    高速排序——JAVA实现(图文并茂)
    WebCollector爬取百度搜索引擎样例
    nyist 202 红黑树(二叉树中序遍历)
    excel转换日期格式,将yyyymmdd类型日期转换成yyyy-mm-dd等日期类型方法
    窗体界面设计03
    窗体界面设计02
    窗体界面设计01
  • 原文地址:https://www.cnblogs.com/rain-blog/p/gtk3-6.html
Copyright © 2011-2022 走看看