




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
10.1Linux图形开发基础10.2嵌入式Linux图形用户界面简介10.3Qt/Embedded嵌入式图形开发基础练习题第10章嵌入式Linux图形用户界面编程
10.1Linux图形开发基础
本节简单介绍图形用户界面GUI的一般架构,主要讨论嵌入式Linux图形开发的基础知识,包括GUI的底层支持库和高级函数库,为后面的进一步叙述奠定基础。10.1.1GUI的一般架构
GUI是GraphicalUserInterface的简称,即图形用户界面。图形用户界面(GUI)是计算机系统中最为成熟的人机交换技术,是计算机与用户之间的对话接口。它是一个图形组成的用户界面。比如,Windows界面、OS2界面等都是GUI。
GUI系统在逻辑上一般可分为以下几层:
(1)最底层I/O设备驱动:直接与输入硬件打交道,完成I/O设备的驱动,包括显示设备驱动、鼠标驱动、键盘驱动等,构成了GUI的硬件基础。
(2)中间层图形引擎:直接和最底层I/O设备驱动打交道,主要完成一些图形操作和图形管理,如画点、画线、区域填充、画窗口及按钮等。
(3)最上层GUI应用程序接口(API):是提供给程序员的编程接口,以快速开发GUI应用程序。
GUI是嵌入式系统中的一个重要问题,越来越多的嵌入式系统要求提供全功能的Web浏览器,而这就要求有一个高性能、高可靠的GUI支持。由于嵌入式系统本身的特殊性,嵌入式GUI要求简单、直观、可靠、占用资源小且反应快速,以适应系统硬件资源有限的条件。另外,GUI还应具备高度可移植性与可裁减性,以适应不同的硬件条件和使用需求。总体来讲,嵌入式GUI应具备以下特点:
(1)体积小;
(2)耗用系统资源小;
(3)上层接口与硬件无关,高度可移植;
(4)高可靠性;
(5)在某些应用场合应具备实时性。10.1.2嵌入式GUI底层支持库
一个能够移植到多种硬件平台上的嵌入式GUI系统,应至少抽象出两类设备:
(1)图形抽象层(GraphicAbstractLayer,GAL):基于图形显示设备,完成系统对具体显示硬件设备的操作,为程序开发人员提供统一的图形设备编程接口。
(2)输入抽象层(InputAbstractLayer,IAL):基于输入设备,实现对不同输入设备的控制操作,提供统一的调用窗口。
嵌入式GUI底层实现基础如图10-1所示。
目前应用于嵌入式Linux系统中比较成熟、功能比较强大的GUI系统底层支持库有XWindow、FrameBuffer、SVGALib、LibGGI等。图10-1嵌入式GUI底层实现基础
1. XWindow
XWindow是Unix的图形界面标准,它是以斯坦福的图形化操作系统WWindowsSystem为基础而发展起来的一套网络透明窗口系统。XWindow系统是目前Linux系统中处于主导地位的桌面图形系统。所有Linux版本的图形界面标准均遵循XWindow,简称X。
XWindow采用标准的客户端/服务器(Client/Server)模式,即参与运行的主体为客户端(XClient)和服务端(XServer)。它由XServer、XClient、X协议、Xlib函数库等组成。
(1) XServer:主要是控制I/O设备的程序,对显示器的输出、键盘和鼠标的输入进行管理,接收输入设备的信息,并将其传给XClient,而将XClient传来的信息输出到屏幕上,提供显示功能。
(2) XClient:也称客户程序,是应用程序的核心部分,与硬件无关。它位于后端,提供处理功能。
(3) X协议:是XWindow系统中各单元间通信的标准,主要负责XClient与XServer间的通信。
(4) Xlib函数库:XWindow客户程序的功能是通过调用Xlib中的函数实现的。
XWindow的这种工作方式为用户提供了两个重要的特性:一个是平台无关性,即应用程序可以在任何其他平台的服务器上显示其界面;另一个是网络透明性,是指服务器和客户端之间通信协议的运作对计算机网络是透明的,客户端和服务器可以在同一台计算机上,也可以不是,一个应用程序不管是在本地运行,还是在远程某台机器上运行,都可以实现在本地显示。
2. FrameBuffer
FrameBuffer是一种独立于硬件的抽象图形设备,是Linux抽象出来的供用户态进程实现直接写屏的设备。它模仿显卡的功能,将显卡硬件结构抽象化。用户可以将FrameBuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读/写操作,而写操作可以立即反映在屏幕上。
FrameBuffer设备提供了若干ioctl命令,通过这些命令,可以获得显示设备的一些固定信息(如显存大小)、与显示模式相关的可变信息(如分辨率、像素结构等)以及伪彩色模式下的调色板信息等。此外,通过FrameBuffer设备还可以获得当前内核所支持的加速显示卡的类型,这种类型通常是和特定显示芯片相关的。在获得了加速芯片类型之后,应用程序就可以将PCI设备的内存I/O(memio)映射到进程的地址空间。这些memio一般是用来控制显示卡的寄存器的,通过对这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。
FrameBuffer本身不具备运算数据的能力,它只暂存经CPU运算后的数据结果,并将结果送到显示器中,中间不对数据做任何处理。它只是一个(提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间的)设备。所以,对于应用程序而言,如果希望在FrameBuffer之上进行图形编程,还需要自己动手完成其他许多工作。FrameBuffer就像一张画布,使用什么样的画笔,如何画画,还需要自己动手完成。
FrameBuffer具有高度的可移植性、易使用性和稳定性。使用Linux内核的FrameBuffer驱动,可以轻松支持1024 × 768 × 32b/p以上的分辨率。目前,在可得到的绝大多数Linux版本所发行的内核中,已经预编译了FrameBuffer支持。
3. SVGALib
SVGALib(SuperVideoGraphicsArrayLib)是一个比较老的图形支持库,是Linux系统中最早出现的非X图形支持库。这个库从最初对标准VGA(VideoGraphicsArray)兼容芯片的支持开始,一直发展到对老式SVGA芯片的支持以及对现今流行的高级视频芯片的支持。它为用户提供在控制台上进行图形编程的接口,使用户可以在PC兼容系统上方便地获得图形支持。但该系统存在以下不足:
(1)接口杂乱。SVGALib从最初的VGAlib发展而来,保留了老系统的许多接口,而这些接口却不能良好地迎合新显示芯片的图形能力。
(2)未能较好地隐藏硬件细节。许多操作不能自动使用显示芯片的加速能力支持。
(3)可移植性差。SVGALib目前只能运行在X86平台上,除Alpha平台之外,对其他平台的支持能力较差。
(4) SVGALib作为一个老的图形支持库,对高级图形功能的支持(比如直线和曲线等)不能令人满意,因此其应用范围越来越小,尤其在Linux内核增加了FrameBuffer驱动支持之后,有逐渐被其他图形库替代的迹象。
尽管SVGALib有许多缺点,支持的显卡种类也不多,但是有许多的游戏及程序还是用它来做开发的。此外,它是Linux
Console下的VGA驱动函数库,如果用户准备在Console下撰写图形功能的程序,目前来说SVGALib是唯一的选择。
4. LibGGI
LibGGI(LibGraphicsInterface)是一个跨平台的绘图库。它试图建立一个一般性的图形接口,而这个抽象接口连同相关的输入抽象接口一起,可以方便地运行在XWindow、SVGALib、FrameBuffer等之上。建立在LibGGI之上的应用程序,不需重新编译,就可以在上述这些底层图形接口上运行。
在Linux上,LibGGI是通过调用FrameBuffer或SVGALib来完成图形操作的,可能速度比较慢。但在某些不支持FrameBuffer或是VGA的系统上使用LibGGI仍然是一种不错的选择。目前,LibGGI的发展缓慢。10.1.3嵌入式GUI高级函数库
1. Xlib及其他相关函数库
Xlib即我们上面所提到的XWindow系统中实现客户程序功能所需调用的函数库。在XWindow系统中进行图形编程时,可以选择直接使用Xlib。它实际上是对底层X协议的封装,可通过该函数库进行一般的图形输出。如果用户的XServer支持DGA(DirectGraphicsAccess,直接图形访问),则可以通过DGA扩展直接访问显示设备,从而获得加速支持。由于Xlib的接口原始而且复杂,使得应用程序界面开发效率低,因此一般用户选择其他高级一些的图形库作为基础,比如GTK(TheGIMPToolkit)、QT等。但GTK、QT等函数库也存在庞大、占用系统资源多的缺点,不太适合在嵌入式系统中使用。这时可选择使用简单而灵活的GUI工具箱—FLTK(FastLightToolkit),它是一个轻量级的图形函数库,特别适用占用资源少的环境。FLTK的主要功能集中在用户界面上,提供了丰富的控件集。
2. SDL
SDL(SimpleDirectMediaLayer)是一个跨平台的多媒体游戏支持库,它是专门为游戏和多媒体应用而设计开发的。它可以运行在许多平台上,包括XWindow、XWindowwithDGA、LinuxFrameBuffer控制台、LinuxSVGALib以及WindowsDirectX等。
SDL提供了对图形、声音、游戏杆、线程等的支持,还提供了对高级图形的支持,比如Alpha混合、透明处理、YUV覆盖、Gamma校正等。
此外,在SDL环境中能够非常方便地加载支持OpenGL
(OpenGraphicsLib)的Mesa库,从而提供对二维和三维图形的支持。可以说,SDL是编写跨平台游戏和多媒体应用的最佳平台,它得到了广泛的应用。
3. Allegro
Allegro库(Allegrolibrary)是一个自由的视频游戏图形库,是专门为X86平台设计的。
Allegro可运行在LinuxFrameBuffer控制台、LinuxSVGALib、XWindow等系统上。它提供了一些丰富的图形功能,包括矩形填充和样条曲线生成等,而且具有较好的三维图形显示能力。由于Allegro的许多关键代码是采用汇编语言编写的,因此该函数库具有运行速度快、资源占用少的优点。但Allegro也存在如下缺点:
(1)对线程的支持较差。Allegro的许多函数是非线程安全的,不能同时在两个以上的线程中使用。
(2)对硬件加速能力的支持不足,在设计上没有为硬件加速提供接口。
4. Mesa3D
Mesa3D是一个支持3D的图形函数库,它有API接口,非常像OpenGL(OpenGraphicsLib,即开放式图形库,是专业的3D程序接口,也是一个功能强大、调用方便的底层3D图形库)。Mesa3D是Linux下OpenGL的取代产品,提供和OpenGL几乎完全一致的接口。
Mesa3D还是一个遵循GPL协议(部分遵循LGPL协议)的自由软件。因此,Mesa3D是一个兼容OpenGL规范的开放源码函数库,是目前Linux上提供专业三维图形支持的唯一选择。
此外,Mesa3D是一个跨平台的函数库,能够运行在XWindow、XWindowwithDGA、BeOS、LinuxSVGALib等多种平台上。
5. DirectFB
DirectFB是一个基于FrameBuffer的图形库,支持部分加速。DirectFB试图建立一个兼容GTK(TheGIMPToolkit)的嵌入式GUI系统。它以可装载函数库的形势提供对加速FrameBuffer驱动程序的支持。目前,该函数库正在开发之中。
10.2嵌入式Linux图形用户界面简介
目前,嵌入式Linux的主流GUI系统主要有Qt/Embedded、MicroWindows、MiniGUI和OpenGUI,这些GUI在接口定义、体系结构、功能特性方面存在很大差别,采取的技术也有所不同。本节我们将分别介绍这几种嵌入式GUI系统。10.2.1Qt/Embedded
Qt/Embedded是著名的Qt库开发商TrollTech开发的,是专为嵌入式设备上的图形用户界面开发而订做的C++工具包。它是面向嵌入式Linux系统的Qt版本,可以运行在多种不同处理器部署的嵌入式Linux操作系统上。
Qt/Embedded的主要特点是:界面美观、色彩配比好;具有与Qt/Windows和QT/X11完全一致的API接口;具有丰富的控件资源;具有模块化和可裁减性,用户可根据实际需要对其进行裁减,以适应不同的应用环境。此外,还有很重要的一点就是移植性好,开发者可以将许多基于Qt的XWindow程序非常方便地移植到嵌入式版本,只需重新编译代码(而不需对代码进行修改)即可使程序本地化。它还是面向对象编程的理想环境。现在,Qt/Embedded被广泛地应用于各种嵌入式产品和设备中,从消费电器(如智能手机、机顶盒)到工业控制设备(如医学成像设备、移动信息系统等)。但Qt/Embedded对于系统资源的要求非常高,需要在较大的存储空间和运行空间上才可以运行,资源消耗大。另外,Qt/Embedded不是开放源码,若需修改Qt/Embedded并在商业产品中发布,则需要支付昂贵的授权费用。
本章后面将重点介绍Qt/Embedded及其编程方法(详见10.3节)。10.2.2MicroWindows
MicroWindows是由美国CenturySoftware公司开发的开放源码的嵌入式GUI项目。
MicroWindows是一个基于典型客户端/服务器体系结构的GUI系统,也是基于分层式设计的,它允许不同的层可以被重新设计以满足系统实现的需要。它分为三层:最底层是屏幕、鼠标或触摸屏和键盘的驱动程序,直接与输入硬件打交道;中间层是一个可移植的图形引擎层,通过最底层提供的服务提供对画线、填充、裁减区域、色彩等的支持;最上层是API,提供给图形化应用程序调用。
MicroWindows支持两种API:类Win32/WinCEAPI和类XLIBAPI的Nano-XAPI。这些API与Win32和XWindow窗口系统兼容,使程序可以很容易地从其他系统上移植过来。其中比较完备的是Nano-XAPI。Nano-X是基于XWindow的一组Xlib风格的API函数库。它被设计成是一个客户端/服务器的环境,在此模式下应用程序与一个客户端的库相连,而这个库则通过一个Unixsocket与Nano-X服务器相连。每个应用程序都通过Unixsocket来传递各种参数,并由服务端来完成客户端的各种请求。为了提高运行速度,还可以通过共享的内存空间来完成数据传递。该项目的主要特色在于提供了比较完善的图形功能,包括一些高级的功能,比如Alpha混合、三维支持、TrueType字体支持等。它不需要其他图形系统的支持,可以充分利用Linux提供的FrameBuffer机制来进行图形显示。MicroWindows基本上是用C语言实现的,因此移植性很强,目前已经移植到包括ARM在内的多种平台上,但也同样导致了系统的运行效率不高。
MicroWindows目前开发的重点是底层的图形引擎,窗口系统和图形接口方面功能比较欠缺,需进一步完善,比如控件或构件的实现还不完备,键盘和鼠标等的驱动还不够完善。同时,MicroWindows的图形引擎还存在许多问题:图形引擎中存在许多低效算法,未经任何优化;代码质量较差,参差不齐,影响整体系统的稳定性,这也是MicroWindows的发展陷于停滞状态的主要原因。10.2.3MiniGUI
MiniGUI是我国国内自主开发的、比较成熟的一个图形用户界面系统,它是由许多自由软件开发人员支持的一个自由软件项目,其目标是为基于Linux的实时嵌入式系统提供一个轻量级的图形用户界面支持系统。
MiniGUI是建立在现有成熟的图形引擎(SVGALib/
LinuxThread)上,支持IntelX86、ARM及PowerPC等硬件平台,并且可在Linux、eCos与VxWorks等操作系统上运行。到目前为止,MiniGUI已经发展成为一个非常成熟和稳定的GUI系统,可广泛应用于包括手持设备、机顶盒、游戏终端等在内的各种高端或者低端的嵌入式系统当中。从整体结构看,MiniGUI是分层设计的:最底层,GAL和IAL提供底层图形接口以及鼠标和键盘驱动;中间层是MiniGUI的核心层,其中包括了窗口系统必不可少的各个模块;最上层是API,即编程接口。
MiniGUI有三个版本:Mini-Threads、MiniGUI-Lite和MiniGUI-Standalone。
(1) Mini-Threads:基于标准POSIX接口中的pthread库,适用于功能较为单一的嵌入式系统,存在系统健壮性不够的缺点。
(2) MiniGUI-Lite:采用多进程运行方式设计的Server/Client架构,应用于多进程的应用场合,为功能复杂的嵌入式系统提供了一个高效、稳定的GUI系统。
(3) MiniGUI-Standalone:以独立的进程方式运行,既不需要多线程,也不需要多进程的支持,适应范围比较广,和其他版本的区别主要在于编译链接的时候代用静态库的方法。
MiniGUI的主要特性如下:
(1)具有完备的多窗口机制和消息传递机制。
(2)支持多字体和多字符集,支持各种光栅字体和矢量字体,可以实现在同一个窗口上同时显示不同语种的文字。
(3)支持简体中文输入法,包括全拼、智能拼音、五笔输入法等。
(4)有丰富的控件资源。
(5)小巧,包括全部功能的库文件大小为300KB左右。
(6)可配置,可根据项目要求进行定制配置和编译。
(7)具有高稳定性、高性能,可移植性好,目前MiniGUI可以在XWindow和Linux控制台上运行。
MiniGUI的缺点是图形功能尚不完善,应用设计比较困难。10.2.4OpenGUI
OpenGUI在Linux系统上存在已经很长时间了,最初的名字叫FastGL,只支持256色的线性显存模式,但目前也支持其他显示模式,并且支持多种操作系统平台,比如MS-DOS、QNX和Linux等,不过目前只支持X86硬件平台。OpenGUI也是一个公开源码项目。
OpenGUI也分为三层:最底层是由汇编语言编写的快速图形引擎;中间层提供了图形绘制API,包括线条、矩形、圆弧等,并且兼容于Borland的BGIAPI;第三层用C++编写,提供了完整的GUI对象集。
OpenGUI比较适合基于X86平台的实时系统,但可移植性稍差。
10.3Qt/Embedded嵌入式图形开发基础
本节将具体介绍基于嵌入式Linux的图形界面开发环境Qt/Embedded,并具体描述Qt/Embedded开发环境的创建和使用方法。10.3.1Qt/Embedded概述
1.关于Qt
Qt是挪威TrollTech公司的一个标志性产品,它是一个支持多操作系统平台的应用程序开发框架,开发语言是C++。Qt开发的最初目的是为跨平台的软件开发者提供统一的、精美的图形用户编程接口,但现在它也提供了统一的网络和数据库操作的编程接口。简而言之,Qt是一个跨平台的C++图形用户界面库,它支持所有Unix系统,当然也包括Linux,还支持WinNT/Win2k、Win95/98平台,目前包括Qt、基于FrameBuffer的Qt/Embedded、嵌入式桌面平台Qtopia。
Qt是以工具开发包的形式提供给开发者的,这些工具开发包包括了QtDesigner(图形设计器)、Makefile制作工具、字体国际化工具和Qt的C++类库等。
Qt的主要特点是:具有丰富的API;优良的跨平台特性;面向对象等。Qt不是自由软件,如果利用Qt编写非免费软件,则需要购买他们的License。由于Qt具有面向对象、技术成熟等优点,因此,目前高端嵌入式设备生产商几乎都选择Qt作为开发工具。
其中,Qtopia(全称QtPalmtopEnvironment)是构建于Qt/Embedded之上的一个类似桌面系统的应用环境,包含完整的应用层、灵活的用户界面、窗口操作系统、应用程序的启动程序以及开发框架。而Qt/Embedded是Qt的嵌入式Linux版本,它是为嵌入式设备的图形用户界面开发而订做的开发工具包,在世界各地被广泛使用。除了在商业上的许多应用以外,Qt/Embedded还是为小型设备提供Qtopia应用环境的基础。Qt/Embedded以简洁的系统、可视化的表单设计和翔实的API让编写代码变得愉快和舒畅。
2. Qt/Embedded的体系结构
Qt/Embedded是Trolltech公司开发的面向嵌入式系统的Qt版本,与X11版本的Qt在最大程度上接口兼容。Qt/Embedded包括类库以及支持嵌入式开发的工具等。Qt/Embedded类库完全采用C++封装,并且有着丰富的控件资源以及较好的可移植性。Qt/Embedded的实现结构如图10-2所示。图10-2Qt/Embedded的实现结构
QWSServer是一个图形事件服务类,它提供了在Qt/Embedded中服务器特定的功能,当运行Qt/Embedded应用程序时,这个应用程序可作为一个服务器运行或连接到一个存在的服务器。如果一个服务器运行,则一些附加操作通过QWSServer类来提供。
Qt/Embedded的底层图形引擎基于FrameBuffer。如10.2节中所述,FrameBuffer(帧缓冲)是一种驱动程序接口,用户可以把FrameBuffer看成是一块内存,既可以从这块内存中读取数据,也可以向其中写入数据,而写操作立即反映在屏幕上。为运行Qt/Embedded,嵌入式Linux内核要支持FrameBuffer。
Qt/Embedded同样是Server/Client结构,Qt/Embedded通过QtAPI与LinuxI/O设备的直接交互,成为嵌入式Linux端口。Qt/Embedded提供自身的轻量级窗口系统,比使用XLib和XWindow更加紧凑,因为它不需要一个XWindowServer或是XLib库,它在底层摒弃了XLib,并采用帧缓冲(FrameBuffer)作为底层图形接口。图10-3为Qt/Embedded与Qt/X11的关系图。图10-3Qt/Embedded与Qt/X11的关系图同Qt/X11相比,Qt/Embedded最显著的效果就是减少了内存消耗。因此,运行Qt/Embedded所需的系统资源可以很小,相对X窗口下的嵌入解决方案而言,Qt/Embedded只要求一个较小的存储空间(Flash)和内存。
3. Qt/Embedded的开发工具
Qt/Embedded提供许多支持嵌入式开发的工具,其中两个非常重要的Qt工具就是:qmake和QtDesigner(Qt图形设计器)。
qmake是一个为编译Qt/Embedded库和应用而提供的Makefile生成器,可以为Qt/Embedded链接库和应用程序生成Makefile文件。qmake可以根据一个项目文件(.pro)产生多种平台下的Makefile文件,使应用程序方便地在多种平台间移植。
QtDesigner是一个具有可视化用户接口的设计工具。Qt的应用程序可以完全用源代码编写,也可以使用QtDesigner来加速开发工作。QtDesigner使用可视化的方式来设计对话框和窗口,而不用手工编写代码。在QtDesigner中还可以使用布局管理器来平滑地设置窗口部件的布局,使用代码编写器编写代码。qmake和QtDesigner是完全整合在一起的。
4. Qt/Embedded的窗口系统
Qt/Embedded包括了它自身的窗口系统。一个Qt/Embedded窗口系统包含了一个或多个进程,其中的一个进程可作为服务器。这个服务进程会分配客户显示区域,以及产生鼠标和键盘事件。这个服务进程还能够提供输入方法和一个用户接口给运行起来的客户应用程序。这个服务进程其实就是一个有某些额外权限的客户进程。任何程序都可以在命令行上加上“-qws”的选项来把它作为一个服务器运行。客户与服务器之间的通信使用共享内存的方法,通信量应该保持最小,例如客户进程直接访问帧缓冲来完成全部的绘制操作,而不会通过服务器,客户程序需要负责绘制它们自己的标题栏和其他式样。这就是Qt/Embedded库内部的处理过程。
客户可以使用QCOP通道交换消息。服务进程简单地广播QCOP消息给所有监听指定通道的应用进程,接着应用进程可以把一个插槽连接到一个负责接收的信号上,从而对消息做出响应。消息的传递通常伴随着二进制数据的传输,这是通过一个QDataStream类的序列化过程来实现的。QProcess类提供了另外一种异步进程间通信的机制。它用于启动一个外部的程序并且通过写一个标准的输入和读取外部程序的标准输出及错误码来与它们通信。
5.字体
Qt/Embedded支持四种不同的字体格式:TrueType字体(TTF)、PostscriptType1字体(TYPE1)、位图发布字体(BDF)和Qt的预呈现(Pre-rendered)字体(QPF)。Qt还可以通过增加QFontFactory的子类来支持其他字体,也可以支持以插件方式出现的反别名字体。
每个TTF或者TYPE1类型的字体首次被使用时,这些字体的字形都会以指定的大小被预先呈现出来,呈现的结果会以QPF的格式被保存下来,这样可以节省内存和CPU处理时间。QPF文件包含了一些必要的字体,这些字体可以通过makeqpf工具取得或者通过运行程序时加上“savefonts”选项获取。如果应用程序中使用到的字体都是QPF格式,那么Qt/Embedded将被重新配置,并排除对TTF和TYPE1类型的字体的编译,这样就可以减少Qt/Embedded的库的大小和存储字体的空间。
Qt/Embedded的字体通常包括Unicode字体的一部分子集,如ASII和Latin-1。一个完整的16点阵的Unicode字体的存储空间通常超过1MB,我们应尽可能存储一个字体的子集,而不是存储所有的字,例如在用户的应用中,用户仅仅需要以Cappuccino字体、粗体的方式显示产品的名称,但是用户却有一个包含了全部字形的字体文件。
6.输入设备和输入方法
Qt/Embedded3.0支持以下几种鼠标协议:BusMouse、IntelliMouse、Microsoft和MouseMan,支持NECVr41XX和iPAQ的触摸屏,还支持标准的101键盘和Vr41XX按键。若通过子类化QWSKeyboardHandler可以让Qt/Embedded支持更多的客户键盘和其他的非指示设备。
在一个无键盘的设备上,输入法成了唯一的输入字符的手段。Qtopia提供了4种输入方法:笔迹识别器、Unicode键盘、图形化的标准键盘以及字典式提取键盘。这些键盘的样式如图10-4所示。图10-4Qtopia的4种输入方法(a)笔迹识别器;(b) Unicode键盘;(c)标准键盘;(d)字典式提取键盘10.3.2创建Qt/Embedded开发环境
一般来说,基于Qt/Embedded开发的应用程序最终会发布到安装有嵌入式Linux操作系统的小型设备上,所以使用装有Linux操作系统的PC或者工作站来完成Qt/Embedded开发是最理想的环境,尽管Qt/Embedded也可以安装在Unix和Windows系统上。
下面介绍在一台装有Linux操作系统的机器上建立Qt/Embedded开发环境的方法。
1.准备软件安装包
首先,准备三个软件安装包:tmake工具安装包、Qt/Embedded安装包和Qt的X11版安装包(注意:QtforX11的版本应比Qt/Embedded的版本旧)。
我们以下列版本的安装包逐步介绍Qt/Embedded开发环境的创建过程:
(1) tmake1.11:用于生成Qt/Embedded应用工程的Makefile文件。
(2) Qt/Embedded2.3.7:Qt/Embedded安装包。
(3) Qt2.3.2forX11:Qt的X11版安装包,用于产生X11开发环境所需要的两个工具。
2.安装tmake
在Linux命令模式下运行以下命令:
tarxfztmake-1.11.tar.gz
exportTMAKEDIR=$PWD/tmake-1.11
exportTMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
exportPATH=$TMAKEDIR/bin:$PATH
3.安装Qt/Embedded2.3.7
在Linux命令模式下运行以下命令:
tarxfzqt-embedded-2.3.7.tar.gz
cdqt-2.3.7
exportQTDIR=$PWD
exportQTEDIR=$QTDIR
exportPATH=$QTDIR/bin:$PATH
exportLD_LIBRARY_PATH=$QTDIR/lib:$LD_
LIBRARY_PATH
./configure-qconfig-qvfb-depths4,8,16,32
makesub-src
cd..命令“./configure-qconfig-qvfb-depths4,8,16,32”指定Qt嵌入式开发包生成虚拟缓冲帧工具qvfb,并支持4、8、16、32位的显示颜色深度。另外,还可以在configure的参数中添加-system-jpeg和gif,使Qt/Embedded平台能支持jpeg、gif格式的图形。
命令“makesub-src”指定按精简方式编译开发包,也就是说,有些Qt类未被编译。Qt嵌入式开发包有5种编译范围的选项,使用这些选项,可控制Qt生成的库文件的大小,但是用户应用时所使用到的一些Qt类将可能因此在Qt的库中找不到链接。编译选项的具体用法可通过“./configure-help”命令查看。
4.安装Qt/X112.3.2
在Linux命令模式下运行以下命令:10.3.3Qt/Embedded的使用
1.信号与插槽(signals/slots)机制
Trolltech创立了一种新的机制—信号与插槽(signals/slots)机制。信号与插槽机制是Qt的重要特征,它是一种强有力的对象间通信机制,它完全可以取代原始的回调和消息映射机制。信号与插槽是迅速的、类型安全的、健壮的、完全面向对象并用C++来实现的一种机制。
1)原理
原始的回调函数机制是指,将某段响应代码和某个按钮的动作相关联,把响应代码写成一个函数,然后把这个函数的地址指针传给按钮,当那个按钮被按下时,这个函数就会被执行。这种方式存在两个问题:一是,回调函数被执行时所传递进来的函数参数不能确保是否正确,容易造成进程崩溃;二是,回调这种方式紧紧地绑定了图形用户接口的功能元素,因而很难把开发独立地分类。然而,Qt的信号与插槽机制是不同的。Qt的窗口在事件发生后会激发信号。程序员通过建立一个函数(称做一个插槽),然后调用connect()函数把这个插槽和一个信号连接起来,这样就完成了一个事件和响应代码的连接。例如,如果一个退出按钮的clicked()信号被连接到了一个应用的退出函数quit()插槽,那么一个用户点击退出键将使应用程序终止运行。此连接过程用代码写出来就是:
connect(button,SIGNAL(clicked()),qApp,SLOT(quit()));信号与插槽机制(如图10-5所示)中的一个对象的信号可以被多个不同的插槽连接,而多个信号也可以被连接到相同的插槽。当信号和插槽被连接起来时,应当确保它们的参数类型是相同的,如果插槽的参数个数小于和它连接在一起的信号的参数个数,那么从信号传递插槽的多余的参数将被忽略。图10-5信号与插槽机制
2)特性
(1)可开发出代码重用的类,因为它不要求类之间互相知道细节。
(2)类型安全的,因为它以警告的方式报告类型错误,而不会使系统产生崩溃。
(3)面向对象的,因为它完全采用C++来实现,利用了C++面向对象的特征。
3)元对象编译器(MetaObjectCompiler,MOC)
信号与插槽机制是以纯C++代码来实现的,实现的过程使用了Qt开发工具包提供的预处理器和元对象编译器(MOC)。MOC的作用是读取应用程序的头文件,并产生支持信号与插槽的必要的代码。开发者没必要编辑或是浏览这些自动产生的代码,当有需要时,qmake生成的Makefile文件里会显式运行MOC的规则。除了可以处理信号与插槽机制之外,MOC还支持翻译机制、属性系统和运行时的信息。
4)实例
如果一个类要使用信号与插槽机制,它就必须是从QObject或者QObject的子类继承,而且在类的定义中必须加上Q_OBJECT宏。其中,信号被定义在类的信号部分,而插槽则定义在publicslots、protectedslots或者privateslots部分。下面定义了一个使用到信号与插槽机制的类:
BankAccount类和大部分C++的类一样。其中,有一个信号balanceChanged(),声明了它在BankAccount类的成员curBalance的值被改变时产生。信号不需要被实现,当信号被激发时,和该信号连接的插槽将被执行。插槽函数setBalance(intnewBalance)的实现代码如下:其中:“emitbalanceChanged(curBalance);”的作用是当curBalance的值被改变后,将新的curBalance的值作为参数去激活balanceChanged()信号。对于关键词“emit”,它和信号、插槽一样是由Qt提供的,这些关键词都会被C++的预处理机制转换为C++代码。
2.窗体(Qwidget及其子类)
一个窗体可以包含很多的子窗体,子窗体可以显示在父窗体的客户区。而一个没有父窗体的窗体我们称之为顶级窗体(一个“窗口”)。一个窗体通常由一个边框和标题栏来装饰。
Qt并未对窗体有什么限制,任何类型的窗体都可以是顶级窗体,也可以是别的窗体的自窗体。同时,标签、消息框和工具栏等可以使用任何颜色、任何字体和语言。Qt窗体使用起来很灵活,它可以被子类化,以满足客户不同的需求。
窗体是Qwidget类或其子类的实例,客户自己的窗体类需要从Qwidget的子类继承(见图10-6)。图10-6Qwidget类的继承图例如:绘制一个模拟的时钟,显示当前时间,并自动地更新时间。
(1)在“analogclock.h”头文件中,定义AnalogClock,代码如下:
AnalogClock类继承了Qwidget,它有一个典型的窗体类构造函数,这个函数有父窗口对象指针和名字指针两个参数。
timerEvent()函数是从QObject(Qwidget的父类)对象继承而来的,这个函数会被系统定期调用。paintEvent()函数是从QWidget继承而来的,并且当窗体需要重画时,这个函数就会被调用。timerEvent()和paintEvent()函数是“事件句柄”的两个例子。应用对象以重载父类对象的虚拟函数events(QEventobjects)的形式接收系统的事件。大约有超过50个的系统事件是较常用的,例如MouseButtonPress、MouseButtonRelease、KeyPress、KeyRelease、Paint、Resize和Close。
(2) analogclock.cpp文件是定义在analogclock.h中的函数的实现源文件,代码如下:构造函数设置窗口的尺寸大小为100×100,并且告诉系统每隔12秒调用一次timerEvent()函数,从而对模拟钟的窗体进行刷新。
在timerEvent()函数中,通过调用QWidget的函数update()就可以告诉Qt,窗体需要立即重画,紧接着Qt就会产生一个绘制事件并且调用paintEvent()函数。
在paintEvent()函数中,一个Qpainter对象用于在窗体上绘制12个刻度以及分针、时针。Qpainter类提供了一种统一的方式用于绘制窗体、位图、矢量图等,它提供了绘制点、线、椭圆、多边形、弧、贝塞尔曲线等功能。一个Qpainter的坐标系可以被转变、缩放、旋转和剪切,这样对象就可以根据它在窗口或者窗体上的位置绘制出一个剪切的视图。剪切可以使窗体绘制时减少闪烁。使用QPainter的子类QdirectPainter可以锁定和直接访问帧缓冲区域。
(3)文件analogclock.h与analogclock.cpp完全地定义和实现了AnalogClock客户窗体类,这个窗体是现在就可以使用的。
3.主窗口(QMainWindow类)
QMainWindow类是为应用的主窗口提供了一个摆放相关窗体的框架。
通常情况下,主窗口的顶部是一个菜单栏,底部有一个状态栏,中间区域可以包含其他的窗体,而菜单栏下方放置着一个工具栏。另外,当鼠标在窗体的某些位置移动时,还会出现一些旁述的按钮,如“提示栏”和“这是什么”帮助按钮等。其中,工具栏可以被拖放到一个停靠的位置,形成一个浮动的工具面板。
1)菜单栏(QmenuBar类)
QmenuBar类实现了一个菜单栏,它会自动地设置几何尺寸并在它的父窗体的顶部显示出来,如果父窗体的宽度不够宽,以致不能显示一个完整的菜单栏,那么菜单栏将会分为多行显示出来。Qt内置的布局管理能够自动地调整菜单栏。Qt的菜单系统是非常灵活的,菜单项可以被动态地使能、失效、添加或者删除。通过子类化QcustomMenuItem,我们可以建立客户化外观和功能的菜单项。
QpopupMenu(弹出式菜单)类以垂直列表的方式显示菜单项,它可以是单个的,也可以是以菜单栏的方式出现的,或者是以别的弹出式菜单的子菜单出现的。每个菜单项可以有一个图标、一个复选框和一个加速器(快捷键)。菜单项通常对应一个动作(例如存盘),分隔器通常显示成一条竖线,它用于把一组相关联的动作菜单分立成组。例如,建立一个包含有New、Open和Exit菜单项的文件菜单:当一个菜单项被选中时,和它相关的插槽将被执行。加速器(快捷键)很少在一个没有键盘输入的设备上使用,Qt/Embedded的典型配置并未包含对加速器的支持。上面出现的“&New”代码的意思是在桌面机器上以“New”的方式显示出来,但是在嵌入式设备上,它只会显示为“New”。
2)工具栏(QtoolButton类)
QtoolButton类实现了一个带有图标、三维边框和可选标签的工具栏按钮。切换工具栏按钮具有开、关的特征,其他的按钮则执行相应命令。不同的图标用来表示按钮的活动,无效、使能模式,或者是开或关的状态。如果用户仅为按钮指定了一个图标,那么Qt会使用可视提示来表现按钮不同的状态,例如按钮失效时显示灰色。
工具栏按钮通常以一排的形式显示在工具栏上。对于一个有几组工具栏的应用,用户可以随便地到处移动这些工具栏,工具栏差不多可以包含所有的窗体,例如QComboBoxes和QspinBoxes。
3)旁述
Qt提供了两种旁述的方式:“提示栏”和“这是什么”帮助按钮。
(1)“提示栏”按钮:通常是小的黄色的矩形,当鼠标在窗体的一些位置游动时,它就会自动出现,主要用于解释工具栏按钮,特别是那些缺少文字标签说明的工具栏按钮的用途。
例如,设置一个“存盘”按钮提示的代码:
QToolTip::add(saveButton,“Save”);
当提示字符出现之后,用户还可以在状态栏显示更详细的文字说明。
(2)“这是什么”帮助按钮:通常指在靠近应用窗口的关闭按钮“×”附近看到的“?”符号的小按钮。它同“提示栏”按钮有些相似,只不过“提示栏”按钮是要鼠标点击了才会显示旁述。对于一些没有鼠标的设备,也许就需要使用“这是什么”帮助按钮。此外,“这是什么”帮助按钮按下后显示的提示信息一般比“提示栏”要多一些。
例如,设置一个存盘按钮的“这是什么”文本提示信息:
QWhatsThis::add(saveButton,"Savesthecurrentfile.");
QToolTip和QWhatsThis类提供了虚拟函数以供开发者重新实现更多的特定的用途。Qtopia并未使用上述提及的两种旁述机制。它在应用窗口的标题栏上放置一个“?”符号的按钮来代替上述的旁述机制,这个“?”按钮可以启动一个浏览器来显示和当前应用相关的HTML页面。Qtopia使用按下和握住的姿态来调用上下文菜单与属性对话框。
4)动作(QAction类)
应用程序通常提供给用户几种不同的方式去执行特别的动作。例如,大部分应用提供了一个“Save”动作给用于存盘的菜单(File|Save)以及工具栏(一个“软盘”图标的工具栏按钮)和快捷键(Ctrl+S)。
QAction类可以让上述过程变得简洁,它允许程序员在一个地方定义一个动作,然后把这个动作加入到菜单或者工具栏。
QAction类可以确保菜单的状态与工具栏按钮的状态保持一致,必要时还可显示提示栏。使一个动作(Action)失效将导致和该动作相关联的菜单项以及工具按钮的失效。同样地,如果用户切换一个工具按钮的状态,那么相关的菜单项也会跟着被选中或不选中。例如,实现一个“Save”菜单项和一个“Save”工具按钮:
4.对话框
Qt提供了许多现成的包含了实用的静态函数的对话框类。
如图10-7所示,QmessageBox类是一个用于向用户提供信息或是给用户进行一些简单选择(例如“yes”或“no”)的对话框类。QprogressDialog对话框包含了一个进度栏和一个“Cancel”按钮。Qwizard类提供了一个向导对话框的框架。
Qt提供的对话框还包括QColorDialog、QFileDialog、QFontDialog和QprintDialog。图10-7QmessageBox与QprogressDialog对话框
5.窗体的布局管理
布局管理的作用是组织管理父窗体区域内的子窗体。它可以自动设置子窗体的位置和大小,并可判断出一个顶级窗体的最小和缺省的尺寸,当窗体的字体或内容变化后,它可以重置一个窗体的布局。布局管理使得图形用户界面的开发高效而简便,也使得提供部分用户接口组件(如输入法和任务栏)变得更容易。
Qt提供了三种用于布局管理的类:QHBoxLayout、QVBoxLayout和QGridLayout。QHBoxLayout布局管理把窗体按照水平方向从左至右排成一行;QVBoxLayout布局管理把窗体按照垂直方向从上至下排成一列;QGridLayout布局管理以网格的方式来排列窗体,一个窗体可以占据多个网格。三者的布局效果见图10-8。
例如,建立两个如图10-9所示的不同尺寸的对话框。图10-8QHBoxLayout、QVBoxLayout和QGridLayout的布局效果图10-9两个不同尺寸
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业内部沟通协作平台建设方案
- 江西省九江市都昌县2024-2025学年八年级上学期期末生物试题(含答案)
- 北京延庆区2024-2025学年高二上学期期末生物学试题(含答案)
- 三农用物资采购管理作业指导书
- 从理论到实践科学探究活动课
- 青稞种植知识培训课件
- 电商直播平台搭建与运营服务协议
- 数学王国里的智慧读后感
- 电子支付平台推广专项资金协议
- 智能供应链管理服务合同
- 公司前台接待礼仪培训
- 人工智能导论知到智慧树章节测试课后答案2024年秋天津大学
- 2024年电力算力协同:需求、理念与关键技术报告-南网数研院(蔡田田)
- (完整版)施工现场机械设备维修保养记录表
- 2024解析:第四章光现象-基础练(解析版)
- 【MOOC】物理化学(上)-武汉大学 中国大学慕课MOOC答案
- 开原市污水处理厂提标改造可研报告
- 黄连素的合成方法研究
- 餐厅排风换气设计方案
- 《南通市介绍》课件
- 中医护理查房课件模板
评论
0/150
提交评论