Linux 下从头再走 GTK+-3.0 (六)

时间:2023-03-10 00:05:33
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 = ; 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

  运行结果如下:

aaarticlea/png;base64,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" alt="" />