轉載:http://www.360doc.com/content/13/1122/15/6828497_331303961.shtml
按照我自己的理解,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碼輸入,還不支持中文輸入。如果誰有這方面的經驗,
不妨來賜教一二。
補充:還有一篇軟鍵盤的參考資料