Linux桌面GUI开发介绍
2011-02-21 13:21:58 阿炯

Linux历史简介

1991年,芬兰大学生Linus Torvalds编写了一个小的操作系统内核,这就是Linux的前身,Linus Torvalds也由此成为了Linux之父。他将Linux系统的源代码在Internet上公布,使Linux的发展受到了众多计算机高手的鼎力相助,Linux从而不断地增加新的特性,不断地提高稳定性。现在,Linux已经成为一个非常流行的操作系统。Linux是遵从GPL协议。也就是说,只要遵从GPL协议,就可以免费得到它的软件和源代码,并对它进行自由地修改。但对一般用户来说,对Linux的源代码进行编译和安装是难度很高的工作。所以,一些公司介入Linux的业务,将Linux操作系统及一些重要的应用程序打包,并提供较方便的安装界面。这些公司所提供的产品一般称为Linux的发布版本。

Linux具有广泛的平台适应性。它在基于Intel公司的x86(也包括AMD、VIA、IDT)的计算机、基于Alpha的计算机,以及苹果、Sun、SGI等公司的计算机上都有相应的发行版本,甚至在AS/400上也能找到相应的版本,还可以在许多PDA和掌上电脑以及嵌入式设备上运行。目前已有为数不少的应用程序可以在Linux上运行。大多数为SCO Unix开发的应用程序都能在Linux上运行(借助于iBCS软件包),甚至还比在SCO Unix上运行速度更快。借助Dosemu,可以运行许多DOS应用程序,而借助Wabi或Wine,还可以运行许多为Windows设计的软件。当然Linux的优点决不止于此,它的出现为我国软件产业赶超世界先进水平提供了极好的机遇,也为我国软件产业反对微软的垄断提供了有力的武器。

Linux的迅速发展随着计算机网络的发展而扩大的。Linux可以说就是网络的代名词。目前Linux主要用于服务器端。在Internet上有很多服务器都在使用Linux。但是,一个操作系统要想得到普及,并占据一定的市场份额,必须要使非计算机专业人士都可以轻松使用这种系统。而Linux作为一种类Unix操作系统,对它的操作一般都是通过复杂的Shell命令进行的。因而,必须有一种简便易学的图形用户接口(Graphics User Interface)GUI,使用户使用鼠标就可以完成大多数工作。

在Linux中,GUI由以下几个部分组成:
窗口系统:组织显示屏上的图形输出并执行基本的文本和绘图功能。

窗口管理器:负责对窗口的操作(比如最小化、最大化、关闭按钮的形状,窗口边框外观等)以及输入焦点的管理。

工具包:带有明确定义的编程界面的常规库。

风格:指定应用程序的用户界面外观和行为。

Linux诞生不久,自由软件社区的计算机专家就开始了KDE项目,目的是提供一个开放源代码的图形用户接口和开发环境。该项目取得了极大的成功,KDE成为许多Linux发布版本的首选桌面环境。GNU/Linux项目因此而得到蓬勃发展。但是,KDE是基于Troll Technologies公司的Qt库的。Qt库是一个跨平台的C++类库,可以用于多种Unix、Linux、Win32等操作系统。Qt并不是遵从GPL或LGPL协议的软件包。1997年由墨西哥国立自治大学的Miguel de Icaza领导的项目组开始了Gnome开发计划。Gnome是GNU Network Object Model Environment(GNU,网络对象模型环境)的缩写。该项目进展很快,由于Gnome项目的成功,1998年11月Qt库的开发者Troll公司宣布修改许可证协议,Qt库也成为自由软件。

1998年发布了Gnome1.0。现在,Gnome已成为一个强劲的GUI应用程序开发框架,并且可以在任何一种Unix系统下运行。Gnome使用的图形库是Gtk+——最初为了编写GIMP而创建的一套构件库,它是基于LGPL创建的,可以用它来开发开放源代码的自由软件,也可以开发不开放源代码的商用软件。Gnome的界面与KDE的界面是类似的(Gnome的目的之一就是创建一套类似KDE的桌面环境),熟悉KDE的用户无需学习就能够使用Gnome。由于以上几个原因,Gnome已经成为大多数Linux发布版本的首选桌面环境。

从用户的角度看,Gnome是一个集成桌面环境和应用程序的套件。从程序员的角度看,它是一个应用程序开发框架(由数目众多的实用函数库组成)。即使用户不运行Gnome桌面环境,用Gnome编写的应用程序也可以正常运行,但是这些应用程序是可以很好地和Gnome桌面环境集成。Gnome桌面环境包含文件管理器,它用于任务切换、启动程序以及放置其他程序的“面板”、“控制中心”(包括配置系统的程序以及一些小东西)等。这些程序在易用的图形界面背后隐藏了传统的UNIX Shell。Gnome的开发结构使开发一致的、易用的和可互相操作的应用程序成为可能。

在Linux下开发GUI程序的首要问题是采用什么样的图形库。Gtk+(GIMP Tool Kit,GIMP工具包)是一个用于创造图形用户接口的图形库它被称为GIMP工具包,因为它最初用于开发“通用图片处理程序”(General Image Manipulation Program,GIMP),Gtk已在大量软件项目,包括Gnome中得到了广泛应用。Gtk+是在Gdk(GIMP Drawing Kit,GIMP绘图包) 的基础上创建的.因为Gtk+和Gnome是用C语言编写的,所以在开发Linux下的GUI程序时使用C语言是非常方便的。如果用C++语言开发基于Gtk +应用程序,可以使用一个名为Gtk的函数库。一般的Linux发布版本中都提供了C编译器gcc或egcs。使用gcc或egcs可以编译C和C++源代码,编译出的目标代码质量非常好,编译速度也很快。各种C编译器都要使用一些C语言实用函数。为了保证程序的可移植性,gcc没有使用通用的C函数库,而是使用一种称为glib的函数库。glib也是Gtk+的基础,它包含一些标准函数的替代函数(如字符串处理函数)和基本数据结构的实现(单向链表、双向链表、树、哈希表等)。glib中所包含的函数消除了某些函数的安全漏洞,使其更加可靠,在不同平台上移植也更加方便。

GTK是用于实现图形用户接口的函数库。在Linux平台上,GUI(图形用户接口)使用的是称为X窗口(XWindow)的系统。X窗口系统是1984年由美国麻省理工学院开发的。在Linux上使用的X窗口系统是一种称为XFree86 的X版本。X窗口系统与Microsoft Windows的图形用户接口有所不同,它是基于客户/服务器的。X服务器在计算机上运行,控制监视器、鼠标和键盘。X客户通过网络与服务器通讯,X服务器为X客户提供图形显示服务。也就是说,X客户和X服务器可能在同一台计算机上运行,也可能在不同的计算机上运行。X窗口系统带有一套低级的库函数,称为Xlib,Xlib提供了许多对X窗口的屏幕进行操作的函数。当然,使用Xlib函数在屏幕上创建构件是很复杂的。GTK要在屏幕上绘制各种构件,就需要与X服务器打交道。但是GTK提供的构件库并未直接使用Xlib,而是使用了一个称为GDK的库。

GDK的意思是GIMP Drawing Toolkit,即GIMP绘图工具包。差不多每个Gdk函数都是一个相应Xlib函数的封装,但是Xlib的某些复杂性(和功能)被隐藏起来了。这样是为了简化编程,使Gdk更容易移植到其他窗口系统(有一个在Windows平台上的Gdk版本)。


Cross Platform C library for GUI Apps

If you are looking for a C++ library, then Qt basically does what you are looking for. If you want to stick to pure C, then Qt is not an option.As a C framework you could use GTK+, it works on Linux, Windows and OS X.

Take a look at the IUP Toolkit. It is written largely in C, and is also easily bound to Lua.

Qt is a C++ library. Other cross platform libraries that you might consider are wxWidgets(C++), and GTK(C). Another option is Tk, which is a GUI library written in C. It comes with Tcl, a scripting language also written in C.


GUI编程基础知识介绍

图形用户界面,英文为Graphical User Interface,简写为GUI。

有许多实现GUI界面的类库,例如C++的QT、MFC等。但是这些类库是如何显示的呢?归根结底,它们都是在计算机屏幕上显示信息,那么计算机是如何绘制屏幕的呢?

计算机把内存中的内容输出到屏幕上,这个操作叫渲染。现代计算机有一个专门的关键部分,用于完成渲染工作,它就是GPUGraphics Processing Unit。


在屏幕上看到的动画或视频,是单一的一帧一帧画面重复绘制的结果,每一帧渲染主要分为六步:
顶点着色器Vertex Shader:顶点着色器主要的目的是把 3D 坐标转为另一种 3D 坐标。
形状装配Shape Assembly:将所有的点装配成指定图元的形状。
几何着色器Geometry Shader:把图元形式的一系列顶点的集合作为输入,通过产生新顶点构造出新的图元来生成其他形状。
光栅化Rasterization:该阶段会把图元映射为最终屏幕上相应的像素。
片段着色器Fragment Shader:对输入片段进行裁切Clipping,裁切会丢弃超出视图以外的所有像素,用来提升渲染效率。
测试与混合Tests and Blending:该阶段还会检查 alpha 值。

完全理解这六个步骤稍微有点困难。大概可以这么理解:CPU送给GPU需要渲染的画面数据,是立体的,就像重叠的窗口一样,是一个立体、有重叠和覆盖性质的内容;GPU收到这些数据以后,先建点连线,构建3D图形,然后在屏幕上投影,将3D图形转化为2D图形,最后裁掉屏幕以外的部分,将像素绘制出来。

GPU本质上绘制的是像素。屏幕上每个像素可以看作是一个带颜色控制的小灯泡,GPU频繁控制这些灯泡的明灭暗淡,以此完成复杂的画面渲染。

程序是如何调用GPU的?

既然屏幕绘制工作是GPU完成的,那么在系统里,软件是如何调用GPU的呢?

无论是什么系统,软件是不能直接控制GPU的。软件向系统发出控制请求,系统通过设备驱动控制特定的计算机设备。驱动全称是设备驱动程序,是添加到操作系统中的特殊程序。驱动中包含有关硬件设备信息,以及设备控制指令。厂商生产了硬件设备,只有厂商自己发布的设备驱动才知道如何控制设备。计算机或其它程序软件没有办法直接控制某个驱动,只有设备驱动可以。


Windows、Mac和Linux,是最常见的操作系统。这些系统的实现是有差异的,显卡之间也有差异,如何消减软件间接调用GPU的差异呢?为此程序员发明了OpenGL。

OpenGL是Open Computer Graphics的简写,是图形学研究人员和程序员以图形学的渲染理论为基础,实现的底层图形算法库。OpenGL封装了不同操作和不同显式驱动之间的差异,让不同软件可以使用一套统一的接口控制屏幕绘制。用稍为正式语句表达,OpenGL是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口API,由近350个不同的函数组成。这些函数并不是天生被支持的,其对显卡的支持是依赖于版本更新。OpenGL像一个适配的插头,处在软件和系统之间。

OpenGL作为一个开放图形库,并不是唯一的,微软的DirectX与它具有相似的功能。

编程语言如何绘制界面?

在屏幕上绘制图形和文本的原理是相同的,本质上计算机没有文本,文本也是一个个字符编码对应的字符图像。计算机绘制文本,是拿字符编码先在字体库中找到对应的矢量图形或位图图形,再将图形绘制到屏幕上。编程语言在屏幕上完成绘制,很少有直接调用显卡驱动的,一般都是通过一个通用的图形类库,间接调用一个或几个图形驱动库OpenGL或DirectX完成的。不同语言有不同的图形类库。

1).C++语言

Filament是谷歌推出的,开源的,一个实时的基于物理的渲染引擎,适用于Android, iOS, Linux, macOS, Windows和WebGL浏览器。它被设计得尽可能小,在Android上尽可能高效。Filament底层引用了OpenGL。

CEF是Chromium Embedded Framework的简写,它可以将一个浏览器内核嵌入到软件中。

2).C语言

GLFW是一个开源的,跨平台GUI类库。它提供了简单的方法,用于创建窗口、读取输入、处理事件等。

小结一下,在计算机中,CPU负责计算,渲染是通过GPU完成的,操作系统Mac、Windows and Linux通过OpenGL或DirectX底层图形库实现对GPU的控制。不同编程语言,通过对OpenGL等底层图形库的封装,都有一些具体的图形引擎库,一般这些引擎库也是游戏引擎库。与此同时,为了方便业务应用开发,不同编程语言也实现了不同的UI组件库,默认实现了像按钮、下拉框、窗体等控件,可以直接使用。

浏览器是一类特殊的系统软件,它可以解析执行js、html标签代码,通过html、css3、js可以快速开发出好看易用的页面。也有UI组件库可以帮助程序员更快地完成开发,微信小程序与之类似。

如果程序员想以代码的形式开发GUI界面,依据语言不同,有不同的选择:
如果是C语言,适合用Nuklear
如果是C++语言,适合用Elements C++ GUI library
如果是Go语言,适合用therecipe/qt
如果是JS,用Vue+Bootstrap+ElementUI最为简单
如果是小程序,用官方组件+WeUI组件
如果是C#,直接用.Net Framework就可以了

但每个语言都有自己擅长做的事情,后端语言写UI一般都是不太合适的。像Go语言,适合开发高并发、高吞吐的后端数据应用,UI并非其长项;像C语言,当下适合做嵌入式、物联网开发,UI也并非其长项;像C++语言,传统类库丰富,适合维护旧系统老软件,直接写UI也并非其长项,C++写界面必须依据业务需求基于某个成熟的UI组件库完成。当下写PC软件,一种流行的做法是基于Electron框架开发。Electron是一个浏览器框架,可以将浏览器嵌入到软件中,使用Html & CSS3 & JS这些成熟的页面技术开发UI界面,同时也可以调用系统资源,做一些js不能做的事情。


Linux的桌面环境

Linux有一套简便易学的图形用户接口(GUI),用户使用鼠标就可以完成大多数工作。在Linux中,GUI由窗口系统,窗口管理器,工具包和风格等几个部分组成。窗口系统用于组织显示屏上的图形输出,窗口管理器用于对窗口的操作如最小化等,工具包是用于编程界面的库,风格是应用程序的用户界面。现在Linux下的桌面环境主要包括KDE和Gnome两种。

KDE(K Desktop Environment)桌面环境目的是提供一个开放源代码的图形用户接口和开发环境。KDE一度成为许多Linux发布版本的首选桌面环境。但KDE是基于QT库的。Qt最初并不能很好地遵从GPL协议,尤其现在是诺基亚公司的资产后。所以,将KDE建立在QT之上是一件危险的事,它将依赖于开发QT库的公司。所以,后来的Linux发行版本中加入了Gnome主面环境。Gnome是GNU Network Object Model Environment(GNU,网络对象模型环境)的缩写。Gnome的发展很快,已成为一个强劲的GUI应用程序开发框架,可以在任何一种UNIX系统下运行。

Gnome使用的图形库是Gtk+构件库,它是基于LGPL协议的。Gnome的界面与KDE的界面类似,熟悉KDE的用户无需学习就能够使用Gnome。所以,Gnome现在已经成为大多数Linux发布版本的首选桌面环境。它是一个集成桌面环境,也是一个应用程序开发框架,由很多的函数库组成。即使用户不运行Gnome桌面环境,用Gnome编写的应用程序也可运行,但是这些应用程序是可以很好地和Gnome桌面环境集成的。Gnome的开发结构使我们可以开发一致和易用的应用程序。

开发所使用的库

Gtk+(GIMP ToolKit,GIMP工具包) Gtk+最初用于开发GIMP,是一个用于创造图形用户接口的图形库。Gtk+是基于LGPL授权的,因此可以用Gtk+开发开放源码软件的自由软件或商业的非自由的软件。

Gtk+是在Gdk(GIMP Drawing Kit,GIMP绘图包)的基础上创建的,Gdk是对Xlib函数的包装。我们一般用GTK代表软件包和共享库,用Gtk+代表GTK的图形构件集。

Gtk+图形库使用一些称为“构件”的对象来创建GUI应用程序,它提供了窗口、按钮、框架、列表框、组合框、树、状态条等很多构件,可以构造丰富的用户界面。

在Gtk+图形库构件基础上,又开发了一些新构件,这些构件都是Gtk+构件库的补充,它们提供了许多Gtk+构件没有的功能,一般把这些构件称为Gnome构件。使用Gnome构件可以使开发界面一致的应用程序变得更加容易。

Gnome的应用程序开发结构核心是一套库,是由C语言编写的,对很多语言都提供了GnomeAPI接口,包括Ada、Scheme、Python、Perl、Tom、Eiffel、Dylan等。它的开发架构包含以下一些内容:

1.非Gnome库
Gnome继承了自由软件一些函数库。其中一些库Gnome应用程序开发架构的一部分,但是不属于Gnome库。可以在Gnome环境中使用这些库函数。主要有以下几种:
Glib库:Glib是Gnome的基础,它是一个C工具库,提供了创建和操作常用数据结构的实用函数。

Gtk+库:Gtk+(GIMPToolkit的缩写),是在Gnome应用程序中使用的GUI工具包。Gnome在基本Gtk+构件集合的基础上添加了许多其他构件。

ORBit库:ORBit是一个用C开发的CORBA2.2ORB。和其他ORB相比,它短小精悍,但速度更快,同时还支持C语言映射。ORBit是以一整套库函数的方式实现的。

Imlib库:Imlib(图片库)提供一些例程,其中包括加载、存储、显示,以及定绘制各种流行的图像格式(包括GIF、JPEG、PNG以及TIFF)的函数。

2.Gnome库
Libgnome库:Libgnome是一些与图形用户接口无关的函数集合,Gnome应用程序可以调用其中的函数。Libgnomeui库—Libgnomeui包含了与GUI相关的Gnome代码。它由为增强和扩展Gtk+功能而设计的构件组成。libgnomeui主要包含:
1).GnomeApp构件一般用来为应用程序创建主窗口。

2).GnomeCanvas构件用来编写定制构件。

3).Gnome内置的pixmap用于创建和使用对话框的例程。

Libgnomeui中还有几种其他构件,如GnomeEntry、GnomeFilePicker等,Libgnorba库—libgnorba提供与CORBA相关的实用程序。

3.其他库
这些库一般使用在Gnome应用程序中,但它不属于Gnome-libs:
Gnome-print库:Gnome-print提供一个虚拟输出设备,一段代码能输出到一个打印预览构件或PostScript文件,还可以输出到其他打印机格式。

Gnome-xml库:Gnome-xml能按照树状结构分析XML,也能按照XML输出树状结构。

Guile库:Guile是Scheme编程语言在一个库中的实现,它使任何应用程序都能带有一个嵌入式的Sheme解释器。

Bonobo库:Bonobo是一种对象嵌入式结构,类似于Microsoft的OLE。

编程语言和编程工具

在Linux下的常用开发语言是C语言,Linux上的很多应用程序就是用C语言写的,当然也可以使用其他语言。因为Gtk+和Gnome是用C语言编写的,所以在开发Linux下的GUI程序时使用C语言是非常方便的。Gtk+也提供与许多其他语言的接口。

一般的Linux发布版本中都提供了C编译器gcc或egcs。使用gcc或egcs可以编译C和C++源代码,各种C编译器都要使用一些C语言实用函数,为了保证程序的可移植性,gcc没有使用通用的C函数库,而是使用一种称为glib的函数库。glib也是Gtk+的基础,它包含一些标准函数的替代函数和基本数据结构的实现。还有许多使用工具可以提高Linux下的编程效率,如gdb是优秀的C语言调试器,有非常丰富的调试指令。automake和autoconf用于由源代码结构配置编译选项,生成编译所需的Makefile文件。

在Linux下开发GUI应用程序,像Windows平台上的可视化快速应用程序开发工具比较少。有几种正在开发的RAD(Rapid Application Development)工具,比如我们以后将要介绍的Glade—一种GUI生成器,可以快速生成创建界面的C源程序。这里主要是对Linux下的开发工具和开发环境做了一个生动、明快的描述。

Linux开发环境之最:
最有用开发语言: C/C++,Perl,Pascal.
最流行的工具集: gtk/gdk,qt,xforms
最好的可视化开发工具: glade,designer,kdeveloper
最cool的代码阅读工具: source navigator
最普及的调试工具: gdb, ddd
最高级(主要指价格高级)的程序跟踪工具: BDM,ICE
最快但最年轻(年轻就是不太成熟)的图形:nano-X,microwindows,minigui

部分名词的意思:
gtk/gdk: 做 GIMP(linux很有名的图象处理软件的工具集
qt: trollteck公司的产品,用qt/x11跟qt/embedd
xforms: 我也不知道怎么写这类程序,反正是经常用到,很成熟,可以吃了
glade: 开发gtk/gdk程序的图形工具,能完成界面的编辑(这比用vim做界面好n 倍,有人曾经用vim以每天2000行程序的速度写过gtk的应用,整整写了一个月,后来用glade用重来,一周就完成了)
designer: 开发qt/x11程序的图形工具,能完成界面的编辑,也可以开发qt/embedded的程序
kdeveloper: 类似VC一样,功能强大
source navigator: redhat公司出的代码阅读器,supper cool.
microwindows: win32接口GUI,又小又快,用于PDA
nano-X: 多任务的microwindows
miniGUI: 类似上面两种图形,国产的,应该比nano-X及microwindows好。