开始认识gtk+

 

最近在工程实践的过程中遇到许多关于图形界面设计方面的内容,特别是关于gtk库的调用,所以通过多方面的学习,终于弄清楚gtk+的用处,以及整个X系统的分层情况。

1,首先来介绍几个概念,以及他们之间的区别:

X Window 系统

在最底层,X包括一种存在与客户端和服务器间的协议。X服务器是响应客户端请求并向用户提供可交互桌面的软件。客户端可以发送请求来创建窗口,绘制文本和图形,这些窗口、文本和图形都会显示在服务器上。一旦用户移动鼠标、按下按键或者单击鼠标,X服务器就会向客户端发送事件通知客户端。X协议只支持所有GUI应用程序所需的最基本的元素。X协议的应用程序编程接口Xlib在该协议上提供了非常简洁的一层。客户就是通过Xlib提供的APIX服务器发送请求,并从X服务器那里接受错误消息和事件。客户端和X服务器可以存在于一台计算机上,也可以在网络上的不同计算机上运行。

GDK

GDK是标准Xlib函数调用的一个基本封装(wrapper)如果你对Xlib很熟悉就不需要来重新熟悉绝大多数的GDK函数所有的函数都是为了提供一个方便直观的风格来访问Xlib函数库另外自从GDK使用GLib在多平台上使用时GDK变得更加的方便和安全

Glib

Glib提供了一系列函数(functions)和定义(definitions)在设计GDKGTK程序时很有用它提供了一些标准c函数库(standard libc)的替代函数比如malloc但在其他的系统上使用时有很多问题

GTK+
   GTK+
是一个小型而高效的控件库具有Motif的外观和风格实际上它比Motif看起来好多了它包含有基本的控件和一些很复杂的的控件:例如文件选择、控件和颜色选择控件 GTK+提供了一些独特的特性(至少我知道其他的控件库不提供他们)例如按钮不提供标签它包含了一个子控件在很多的时候是一个标签但是这个子控件也可以是一个映射图像或者任何其他的程序员想要的集合在整个的库中你随处可见这种伸缩性
       GTK
+由两部分组成,GTKGDK GTK层为C语言提供了一个对象模型,并为UI工具包提供了最基本的widget它是上层GUI派生的基础 GTK是依赖于GDKGDKXlib的一个底层包装,Xlib库直接与X服务器对话。除了Xlib以外的任何部分都是基于GLib的,它是一个有用的C函数库,提供了很多实用程序和可移植的功能以及一组容易被C语言使用的容器。

 

2,然后再介绍两种层次结构

Gnome程序的层次结构

Gnome的开发基础结构是围绕一组函数库的所有的内容都是用可移植的ANSI C语言写成的,可以用于所有类UNIX系统,与图形相关的函数库依赖于X Window系统

   一个Gnome程序使用多个库组成的层次结构: Gnome库在最高层,包括帮助例程,类和特殊的widget,并为应用程序提供一个基础架构。第二层是GTK它是GTK+库的一部分。这个库提供了基本的工具包和widget来创建GUI应用程序。大多数GUI是直接用GTK编写的GTK同时为Gnome库提供了一个功能强大的对象系统。 再下一层是GDK它简单的对X函数库进行了包装,只有在我们进行特殊绘画或设置窗口的特殊属性的时候才会用到它 最下面一层是Glib,它是C的一个实用程序库,包括可移植性和一些实用程序功能,以及一些容器类,例如:链表,可变数组,变长字符串,HASH(貌似是哈西表),缓存,一个事件循环和其他有用的结构

 

X系统的分层

X系统中,由下而上关系是Xlib-->GDK-->GTK。我们先看GDK,大家知道,XGDK都是一个事件驱动系统,也就是说,它们 的工作方式就是从底层系统的事件队列中不停取事件,然后进行相应的处理。当然,这个事件队列是更底层的系统产生的(比如GDK的事件队列是从X中取得,X 又从。。。。)

这里,事件是什么?是一种结构(一种带有信息的机械动作),这个结构包括许多要素,比如(鼠标单击,在窗口A上,坐标为XY)就是一个事件,可见,事件是自包含的,它含有你所想要的全部信息,根据这些信息,你就可以做许多事。比如,在GDK的基础上你可以设计一个主循环,假设你有两个小部件AB,你想在当鼠标 A上单击时(一个事件)B上显示“saga"。你可以这样做你的主循环:1初始化,做一个表,表中有两项,分别为ABA为空,B中放两项 clicked-->display表示当B收到clickeddisplay(显示saga)2循环:取事件,若a单击事件发生的地点在 A(看事件这个结构中的位置项,可以是坐标,也可以是对应的窗口),则AB发出一个"clicked"(记住这句话但是怎么发出的呢,是通过底层的事件机制告诉给b么?)B收到"clicked" displayb单击不发生在A上,丢掉这个事件,再取下一个事件进行判断,周而复始。看到吗?假设屏幕上有几十个小部件,每个小部件就如AB那样 做一些表,放入自己收到"clicked"(或其它的什么)时要做的事(一个函数),在主循环中查到(根据位置)在某个小部件上发生"clicked" 查表并做相应的事件(函数)它的功能就如同GTK一样强大了。把这当成一个框架,任何人用它,只要填好那个表,再写好收到"clicked"后要执行的 函数就可以了,很方便吧,你都可以做系统架构师了。GTK就是这样做的!(当然GTK还做了太多的其它的事,看它的名字"Gimp ToolKit"--画好小部件是它要做的正事)
 
将一些词用正式术语替换,这个过程就是这样:主循环收到一个事件(鼠标单击,在窗口A),便由窗口AB发出一个信号"clicked"B(在这儿就 是查表了)有没有注册了的回调函(注册--就是那个g_connect_signal的作用了),有一个注册了的函数,就是display(。。。) 便去执行这个函数(B上显示saga)

大家看到A是向B发一个信号,其实也可以向自己发一个信号,就是这样描述:当有一个发生在A上的单击事件时,AA发出一个"clicked"信号,A 到后在A上显示"saga"!而且大多数编程人员的实现中,A就是向自己发一个信号,也就是说,常常是经历了某个事件(A经历了单击这个事件,说经历,是 因为发生在自己身上)的小部件发出一个给自己的信号并处理这个信号,有点晕?这正是常常把事件与信号混淆的原因!!!(because the the one who generates event is the one who send the msg and deal the msg itself)

 

3,最后是信号与事件的区别

信号与事件

——事件Events是从X server收到的消息流。事件(Event)是一个Gdk/Xlib概念。

——信号是GtkObject和它的子集(subclasses)的特性他们和任何的输入流都没有关系。信号是对象(object)发出的。只是为了调用回调函数(就是发出信号时调用)

信号(Signals)和事件(events)有关是因为GTK控件 (GtkWidget)通常收到一个事件的时候发出一个信号这纯粹是为了方便所以你可以在控件收到一个事件的时候调用一个回调函数当你按下一个按钮 的时候会发出一个信号所以才让人认为信号和事件有天生的联系

1事件驱动着Gtk的主循环等待事件然后处理它GTK 是一个事件驱动的工具包,意味着它会等在 gtk_main() 那里,直到下一个事件发生,才把控制权传给适当的函数。

2信号只是保持了一个回调函数列表然后调用回调函数(就是发出信号)。这样的作用是:控制权的传递是使用信号的办法来完成的。

ps:在这里是否可以理解事件是源,事件驱动信号发生。所以事件是底层的X信号是上层的Gtk

 

这样我们就可以总结一些区别了:

1信号总是由一个小部件发出的。而事件是下层驱动产生的(当然,大多数情况是由人发出再经过系统、X的包装,传到GDK),它自身带有事件产生的位置信息。

2它们之间有许多相似的函数,比如你可以用gtk_widget_set(add)_events让一个小部件监听一个事件(比如你可以偷听在不同小 部件上发生的鼠标单击),就象听一个信号一样,不同的是你可以听到在其它部件上发生的事件,却不能听到不是发给你的信号。

3信号有一个传递机制,比如A并没有处理这个信号的回调函数,就会把这个信号向父类传,直到有人处理或到最顶层。而事件始终在事件队列中,你可以向操作系统说(术语就是注册)我关心鼠标单击事件,有了告诉我,你不说,它就不告诉你!

4还有许多细节上的差异。

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值