分类: 嵌入式
2010-10-30 10:51:56
最近看到很多人讨论关于QtEmbedded软键盘的问题, 问的最多的主要集中在以下方面:
1、怎么才能写出不和程序窗口争夺焦点的输入法软键盘
2、怎么把软键盘的键值发送给焦点widget
3、其他关于中文输入法的问题
首先必须明确, 软键盘其实是输入法的一种表现形式, 所以我们在设计实现软键盘时先要去寻找系统中是否提供了输入法的API。 有些人还有疑问:“为什么非得用输入法的API呢? 我用普通的Qt API一样可以实现类似的东西亚!” 但事实并非如此,或许你可以在你的程序中写出一个看起来很像输入法的软键盘窗口, 但要知道普通的QtE API是不能跨进程的, 如果你的系统包含多个程序就必然歇菜! 相反, 好消息是QtE的输入法API可以保证你的输入法在各个QtE的程序里都可以使用。 ^_^y
限于QtEmbedded文档的不够系统, 可能很多人在大海里捞针样的寻找之后终告放弃,转而采用其他古怪的方法实现软键盘需要的功能。 本文旨在提供入门的输入法框架介绍, 并介绍软键盘的实现方法, 让大家少走一些弯路。
下面将介绍输入法中最重要的基础和框架, 以一个简单的软键盘为蓝本, 后边会捎带提提普通的键盘输入法(如像scim这样的中文输入法)在QtEmbedded中该如何实现。
QtE的输入法框架从较早的QtE2到现在的QtE4没有太多的变化, 一个输入法必须提供一个QWSInputMethod类的实例, 所以在输入法中要实现一个QWSInputMethod类的派生类, 在此派生类中显示和操作软键盘widget并完成与输入法框架的通讯。 QWSServer进程调用QWSServer::setCurrentInputMethod(QWSInputMethod*)激活该输入法后, 输入法框架会把应用程序的信息发送给QWSInputMethod类, 由QWSInputMethod的虚函数来处理。 所以最核心的部分变成怎样去实现一个QWSInputMethod的派生类,另外怎么让你的软键盘窗口能和程序输入窗口和QWSInputMethod和平共存。 下面这篇QtE的文档提及了如何解决本文开头提出的第一个问题:
其核心是软键盘widget需要设置Qt::Tool属性, 以保证它不和焦点窗体争夺焦点
关于第二个问题可以在QWSInputMethod类的文档中找到大部分答案。 QWSInputMethod提供的sendPreeditString方法负责将预处理的文本发送给焦点窗体, 一般情况下编辑器会将此文本显示为带下划线或虚线的文本, 表示这是编辑过程中的半成品; 然后QWSInputMethod::sendCommitString函数负责发送最终用户确认的文本给编辑框。
解决了这两个问题我们就可以写出一个简单的软键盘输入法了, 呵呵, 可能还有人不相信软键盘如此容易实现, 所以笔者提供了一个小的软键盘例子演示如何解决上面两个问题。 这个例子很简单, 包含main.cpp和mainwin.*代表qte的server进程, 而imframe.*则是QWSInputMethod的派生类, inputwidget.*则是软键盘窗体。 程序里还用到了以前blog中介绍的QSignalMapper类, 如果对此类不熟悉的同学看看这篇帖子扫扫盲。 其他不明白的可以blog或bbs留言。