按照我自己的理解,qt模拟键盘分三个层次的模拟。 1.单线程的模拟。 2.qt框架内的模拟,可以跨线程的。 3.在操作系统的图形界面内模拟,相当于模拟了一个输入法。
第一种,一般就是添加多个按键,QToolButton,QPushButton都可以,每一个按键,对应一个SLOT槽。然后 在槽内实现对应输入框的显示。这种实现的原理比较简单,缺点如果按键较多,程序就非常臃肿。而且只能 在一个线程中运行,如果是多线程,就需要重复实现。
第二种,利用qt给定的设计输入法的类QInputContext或者QWSInputMethod实现。QInputContext用来设计 通用平台的输入法 QWSInputMethod只用来设计嵌入式平台的输入法。 QInputContext实现的输入法: 首先,设计一个显示各种按键的面板。每个按键都可以通过QSignalMapper将clicked()信号,附加一个 int型或QWidget型的信号然后利用这个信号来识别按下的具体是哪个键 其次,处理好焦点问题。将按键面板的窗口属性设置为Qt::tool,并重新实现event函数。具体就是如果它 获得了焦点,就将焦点移到上一个焦点窗体。也就是它不能获得焦点 最后,在继承QInputContext时,要新实现 QString identifierName(); bool isComposing() const; void reset(); QWSInputMethod实现的输入法 设计输入面板,这个和前一种方法一样。同样要将按键面板的窗口属性设置为Qt::tool。然后在继承 QWSInputMethod的类中实现三个函数 void PreeditContent(QString newcontent); 能过面板类将信号先连接到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> 要加"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码输入,还不支持中文输入。如果谁有这方面的经验, 不妨来赐教一二。 |
|