QT是挪威的Trolltech公司开发的一个跨平台的C++的GUI组件,而Qtopia智能手机开发平台则是基于QT的桌面系统,是Trolltech为采用嵌入式Linux操作系统的消费电子设备而开发的综合应用平台。在现在竞争日趋激烈的智能手机开发平台上,Qtopia以他的众多优点,如自身提供丰富的窗口部件集,具有面向对象的特性,易于扩展,真正的组件编程等逐渐为越来越多的手机开发工程师所熟悉和使用。 本文通过结合对QT开发平台中特殊通信机制的简略介绍,重点介绍了如何在Qtopia平台上实现输入法软键盘的策略,以及相应的优化改进,使读者能大致了解QT平台上开发的流程,对熟悉Qtopia平台以及在此平台上的开发都有很好的辅助作用。 1 Qtopia内部特殊的通信机制 在Qtopia内部,共有3种特殊的通信机制:Qcop协议,信号-槽(signal-slot)机制和FIFO机制,其中大量应用的是Qcop协议和信号一槽(signal-slot)机制。 Qcop是QT内部的一种通信协议,主要用于不同的客户之间在同一地址空间内部或者不同进程之间的通信,大致的使用流程是在函数中使用Qtopia定义好的类:QcopEnvelop,将相关的消息和参数发送出去。然后在需要对Qcop信息进行处理的地方定义好接收管道,同时再定义相关的消息(message)处理函数,根据发送过来的不同的message进行不同的处理。而信号(signal)-槽(slot)机制则是指一种高级接口,应用于C++的对象之间的通信,他取代了很多GUI工具包中的回调函数,分别由以下步骤实现: (1)当对象改变状态时,相应的信号(signal)由该对象发射(emit)出去; (2)而槽(slot)是用来接收指定的signal的,他就是普通的对象成员函数。 当signal发出的时候,不相关的组件不知道他代表什么,只有定义好的接收slot才能处理signal信息,从而做到了真正的信息封装。通过专门的函数connect来指定接收signal的slot,而且signal和slot之间可以一对一,一对多,多对一,多对多,还可以signal触发signal,非常的灵活和易用,对应关系如图1所示。 图1 signal与slot的对应关系 与在其他平台上开发的输入法模块明显不同的是,在Qtopia平台上开发输入法模块充分利用了其内部特殊的通信机制,尤其是信号-槽(signal-slot)机制,从而使输入法的实现简洁明了。 2 软键盘功能中各部分模块的实现 现在准备在Qtopia平台上实现软键盘的功能。代码都是在PC上的Qtopia模拟器环境下做的编写和修改。Qtopia模拟器是Trolltech公司提供的辅助开发工具,用于在PC上模拟出手机开发板上的开发情况,方便Qtopia工程师进行代码修改和调试。而最后的调试则是在debug板上进行的,通过看实际的效果,有助于发现一些在模拟器上容易忽略的问题。为了简化叙述手段,将可能提到的调用函数的形参全部省去,如emit key(int unicode,int scancode,int mode,bool press,bool repeat)省略为emitkey(),具体的函数调用实现请参阅QT的帮助手册。 项目计划总共要实现拼音,英文和符号输入法键盘共3个模块,现在重点描述最具有代表性的拼音输入法键盘的实现。其键盘草图如图2所示。 图2 拼音输入法键盘草图 下方的软键盘即是输入按钮所在的地方,上方2条选择栏分别是输入的拼音显示栏和与拼音对应的汉字候选栏。要完成这个键盘必须实现如下几个模块: - 拼音输入法引擎模块 用来实现与拼音匹配的汉字。
- 智能匹配模块 搜寻与输入拼音相接近的汉字以及联想的词组。
- 汉字选择栏 显示模块显示对应的汉字。
- 拼音输入栏 显示模块显示输入的拼音。
- 软键盘输入界面模块 接收用户的输入,转给Qtopia系统。
拼音输入法引擎模块直接购买了第三方厂商的产品,智能匹配模块则是随着引擎一起购买而来的,但是由于厂商开放了模块的源代码,在实现的时候按照客户的需要做了一些小小的改动,如调整了一些原来匹配字符顺序的不合理,提高了某些字符的优先级等。 汉字选择栏模块类picksboard.cpp和拼音显示栏模块类pickboardPY.cpp都继承自QT中的Qframe类,在确定选择栏的尺寸之后,采用输入法引擎模块的字符显示接口, 即可以正确地显示需要选择的字符。 输入法界面模块是重点要解决的模块,于是先初始化键盘类keyboardconfig.cpp,这个类继承自QT 中的Qobject类 然后在调用软键盘的时候使用qtopia中的绘图函数drawLine()和setPen()画出一个软键盘。然后需要达到的目标是:在软键盘上点击所见的字符后,能正确地显示字符;点击软键盘上的某个按钮后需要有按钮反白,给使用者视觉上以按下按键的效果。 实现原理是在Qtopia中提供了一个key()信号。根据前面说过的信号-槽(signal-slot)机制,在点击软键盘按键时,发送相应的带参数的key()信号给Qtopia系统,即emitkey(unicode,scancode,mode,true,false),Qtopia系统中有专门的接收key()信号的槽来根据参数unicode,作为字符的惟一识别标志,在对应的unicode表中寻找对应的字符,显示在屏幕上即可,十分简单高效。 按键反白的效果采用了在按下按键时对键盘进行重绘,将按下的那个按键区域填涂上反白的颜色,而放开按键的时候再次对键盘进行重绘,将按键区域填涂上原键盘的颜色。即按照如下的一个流程:初始化一绘制软键盘(弹出软键盘)一点击触摸屏一重绘软键盘(按键反白显示)一释放触摸屏一再次重绘软键盘(软键盘正常显示)。 3 组合模块,软键盘的实现 软键盘的实现流程如图3所示。 图3 软键盘实现流程图 现在前期的准备工作都已经完成,应该在合适的位置组成软键盘。在Qtopia模拟器的显示屏上,为了不与其他控件产生冲突,也为了选择栏和软键盘的相对位置有个根据的基准,还需要专门为软键盘的显示设置一个容器(container)。因此再写出一个类keyboardContainer.cpp,每次在弹出软键盘之前,先初始化和弹出container,然后选择栏和软键盘的显示就以这个容器的显示位置为依据,从而显示在正确的位置上,这样处理还有一个好处就是:要调整整个软件盘的位置,只要调整容器的位置即可,而不用去改动其他代码。 于是在完成keyboardContainer.cpp类之后,将选择栏和软键盘在容器里的正确位置显示,然后将容器在整个Qtopia模拟器上的正确位置显示即可,经过测试,可以达到目的。 4 软键盘实现策略的改进和优化 将代码下载到debug板上进行调试时,发现在软键盘弹出时有比较明显的刷新迟滞和闪烁现象,不能达到弹出和反白显示正常的要求。经过跟踪和分析,以及对调试板性能的估计,发现原因在于:采用ARM 架构的debug板上的CPU主频较低,无法很顺畅地即时重绘软键盘,而在模拟器上调试时,由于PC的CPU频率较高,则不影响软键盘的重绘。 解决问题的关键在于提高重绘键盘的速度。于是考虑用贴图来代替重绘,实现策略是将软键盘图片先保存在内存中,在需要的时候直接调用内存中的图片,这样就省去了重绘的时间,可以大大提高速度。按键反白效果的显示,也是用反白颜色的按键小图片来代替对按下键的填涂颜色,同样不需要对键盘进行重绘。经过计算,图片占用内存约100 kB,对于智能手机上64 MB左右的内存大小来说,完全承受得起。Qtopia中也提供了bitBlt()函数来将内存中的图片直接显示在屏幕上。 还有一点要注意,由于初始化图片的数量比较多,会影响开机的速度,可以将初始化图片的时间推后,考虑到一般用户使用软键盘的习惯,将初始化图片的时间定在完全开机后的1~3 s是可行的。用Qtopia中的定时器类函数可以顺利地实现这一点。在优化之后,再次将代码下载到debug板上,经过测试,发现键盘的弹出和反白显示都没有停滞感,功能也可以完全实现,从而顺利地完成了Qtopia上的拼音输入法软键盘模块的实现。 5 结语 在现在的手机开发中,第三方厂商所能提供的支持越来越多,但是在任何一款新手机的开发里,输入法模块的实现都是必须自行开发的。Qtopia提供了大量灵活的函数,在嵌入式系统这个内存小,CPU主频相对较低的特殊环境下,为顺利实现模块功能提供了很大的选择余地。因此,这个Qtopia平台上输入法模块实现的例子有嵌入式开发人员可以借鉴的地方,同时也说明了Qtopia平台以他优良的扩展性能,一定能够在竞争激烈的手机开发平台市场中占有自己的一席之地。
|