按照我自己的理解,qt模拟键盘分三个层次的模拟。
1.单线程的模拟。
2.qt框架内的模拟,可以跨线程的。
3.在操作系统的图形界面内模拟,相当于模拟了一个输入法。
第一种,一般就是添加多个按键,QToolButton,QPushButton都可以,每一个按键,对应一个SLOT槽。然后
在槽内实现对应输入框的显示。这种实现的原理比较简单,缺点如果按键较多,程序就非常臃肿。而且只能
在一个线程中运行,如果是多线程,就需要重复实现。
第二种,利用qt给定的设计输入法的类QInputContext或者QWSInputMethod实现。QInputContext用来设计
通用平台的输入法
QWSInputMethod只用来设计嵌入式平台的输入法。
QInputContext实现的输入法:
首先,设计一个显示各种按键的面板。每个按键都可以通过QSignalMapper将clicked()信号,附加一个
int型或QWidget型的信号然后利用这个信号来识别按下的具体是哪个键
其次,处理好焦点问题。将按键面板的窗口属性设置为Qt::tool,并重新实现event函数。具体就是如果它
获得了焦点,就将焦点移到上一个焦点窗体。也就是它不能获得焦点
最后,在继承QInputContext时,要新实现
QString identifierName();
QString language();
bool isComposing() const;
void reset();
bool filterEvent(const QEvent* event);
QWSInputMethod实现的输入法
设计输入面板,这个和前一种方法一样。同样要将按键面板的窗口属性设置为Qt::tool。然后在继承
QWSInputMethod的类中实现三个函数
void PreeditContent(QString newcontent);
void ConfirmContent();
updateHandler(int type);
能过面板类将信号先连接到PreeditContent(QString newcontent)槽,然后利用ConfirmContent()确定
输入内容。updateHandler(int type)和第一种方法介绍的bool filterEvent(const QEvent* event)函数差不
多,都是来控制输入面板的显示和隐匿,以及面板位置更新。
第三种,这个要调用到操作系统的图形系统的系统函数。设计面板,转换clicked()信号都是一样的步骤。
然后,就是要将发出的信号,转换成事件,通过
QApplication::sendEvent()将事件发去。中间也有焦点的处理,主要是获得焦点窗体,这些要调用到具体
系统的函数。这样就可以设计出类似输入法一样的软件。
我本人实现了第二个层次的qt模拟键盘。具体代码,参见:http://download.csdn.net/detail/yongan1006/4366542
效果:
实现的时候,注意的细节:
1.这两种版本的qt模拟键盘要在qt4.6以上的版本中才可以正常运行
2.由于按键的键值是通过xml文件配置的,所有在包含处理xml文件相关类时,
注意qt4.5与qt4.6以上之间的差别。即
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
要加"QtXml/"在QDomDocument和QDomElement前。还要在工程文件的开头
加上这么一句"QT += xml”。要不然,编译会有问题。
3.在嵌入式版本的qt模拟键盘程序中,如果注意到第2点的差别,修改后也可以
在qt4.5上运行。
4.书写xml文件时,注意xml文件的实体引用。
5.在设计输入面板时,我的程序中QPushButton的objectname,为QPushButton_*,
'*'为阿拉伯数字,它的大小是和xml文件属性"nr"是对应的。所以裁剪键盘时,注意
其对应关系。而且QPushButton的focusPolicy均为nofocus
6.不知是不是qt本身的bug,它没有办法在QPushButton中显示字符‘&’,所以要显示
这个字符,就用图片代替了。
7.嵌入式平台中,可能不支持".ico"后缀的图片。我的上面不支持。
目前,两个版本的程序只支持ascii码输入,还不支持中文输入。如果谁有这方面的经验,
不妨来赐教一二。