在 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="" />

Linux 下从头再走 GTK+-3.0 (六)的更多相关文章

  1. Linux 下从头再走 GTK+-3.0 (一)

    原本由于项目需求在 Linux 下学习过一段时间的 GTK+2.0 图形开发,时隔一段时间,想真正深入学习一下 GTK . 这次直接从头学习 GTK+-3.0 ,并写下博文便于日后查看,也方便新手入门 ...

  2. Linux 下从头再走 GTK+-3.0 (五)

    实践中表明,纯粹利用 gtk 函数来创建 UI 是很繁琐的事,需要编写很多代码.怎样才能快速统一的建立 UI 布局呢? 可喜的是 GTK 提供了一个 GtkBuilder 用于快速创建界面.它读取一个 ...

  3. Linux 下从头再走 GTK+-3.0 (三)

    之前我们为窗口添加了一个按钮,接下来让这个按钮丰富一点.并给窗口加上图标. 首先创建 example3,c 的源文件. #include <gtk/gtk.h> static void a ...

  4. Linux 下从头再走 GTK+-3.0 (四)

    实际的应用中,往往有很多个控件, 同样GTK提供了很多种布局方案,Box, Fixed , Table , Grid 等. 接下来试试网格布局 Grid. 我们创建 example4.c ,内容如下: ...

  5. Linux 下从头再走 GTK+-3.0 (二)

    仅仅创建一个空白窗口是不够的,下面我们为创建的窗口添加一个按钮. 以 Hello,World!为例. 首先创建一个源文件:example2.c 内容如下. #include <gtk/gtk.h ...

  6. Linux下安装二进制版mysql-8.0.15

    1.添加用户## 添加用户组groupadd mysql## 添加用户,指定用户home目录useradd -g mysql mysql -d /data/mysql## 解压下载的mysql二进制包 ...

  7. linux下安装mysql5.7(centos6.0)

    注:因为网络原因,这个mysql安装是我以前在学校的时候找到的一个安装包,不过也找到了下载的地址:http://www.itmop.com/downinfo/143061.html下载完成后,把文件上 ...

  8. linux下如何编译安装gcc-8.3.0

    1. 获取源码 wget https://mirrors.ustc.edu.cn/gnu/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz -P ~ tar xvf gcc-8.3.0.t ...

  9. linux下使用yum安装新版php7.0

    这两天又装了一下虚拟机,又要编译lnmp,还要弄各种拓展,很麻烦,能不能直接yum安装呢?答案是可以的! 1.首先要更新yum源,不然是默认的老版本,一般都在5.6及以下,但是php7都出来好久了,性 ...

随机推荐

  1. C# 泛型简介

    摘要:本文讨论泛型处理的问题空间.它们的实现方式.该编程模型的好处,以及独特的创新(例如,约束.一般方法和委托以及一般继承).此外,本文还讨论 .NET Framework 如何利用泛型. 下载 Ge ...

  2. ThreadLocal的基本原理与实现

    一.概念 首先,ThreadLocal并不是一个Thread,这个类提供了线程局部变量,这些变量不同于它们的普通对应物,因为访问某个变量的每个线程都有自己的局部变量,它独立于变量的初始化副本. 二.基 ...

  3. ASP.NET MVC4 数据库连接(EF6.0)

    我的博客原文地址:http://www.star110.com/Note/ReadArticle/60641215331146140041.html 环境:.NET MVC4 + EF6.0 连接数据 ...

  4. 【poj 3080】Blue Jeans(字符串--KMP+暴力枚举+剪枝)

    题意:求n个串的字典序最小的最长公共子串. 解法:枚举第一个串的子串,与剩下的n-1个串KMP匹配,判断是否有这样的公共子串.从大长度开始枚举,找到了就break挺快的.而且KMP的作用就是匹配子串, ...

  5. Oracle 中 call 和 exec的区别

    今天发现了一个小东西,觉得很有意思,查找了一些资料,跟大家分享一下: 在sqlplus中: 在第三方提供的工具(如:plsqldev) 总结: exec是sqlplus的命令,只能在sqlplus中使 ...

  6. phpcms--使用添加php原生支持

    1,phpcms模板中有时候要添加一些php相关变量这个时候要使用原始php的东西,可以如下加入 {php $no_wq_id=$r[id] ;}其中$r[id]是通过{pc:get sql=&quo ...

  7. 静态导入Static import

    静态导入Static import 要使用静态成员(方法和变量)我们必须给出提供这个静态成员的类. 使用静态导入可以使被导入类的静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名 ...

  8. jquery TypeError: 'undefined' is not a function (evaluating 'elem.nodeName.toLowerCase()') [jquery.js:1904]错误原因

    今天,某个环境报了个js错误,TypeError: 'undefined' is not a function (evaluating 'elem.nodeName.toLowerCase()') [ ...

  9. 深入理解MySQL开发性能优化.pptx

    深入理解MySQL开发性能优化.pptx,依旧上传baidu pan http://pan.baidu.com/s/1jIwGslS,视频暂未出,培训完成后会更新.

  10. [ASP.NET MVC] 使用Bootstrap套件

    [ASP.NET MVC] 使用Bootstrap套件 前言 在开发Web项目的时候,除了一些天赋异禀的开发人员之外,大多数的开发人员应该都跟我一样,对于如何建构出「美观」的用户接口而感到困扰.这时除 ...