Qt编写可换肤的中文双拼汉字输入法
時間過得真快,不知不覺已到2015年,農歷春節一眨眼就過去了,端正狀態收拾心情整裝待發出發。
曾經有段時間,我有一個很執著的夢想,我要導演出一部空前絕后的巨幕。不過現實無情地碾碎我的夢想,也同時將我推進了人生的低谷。
我開始思考,思想很多很多我以前總是回避的問題,在一次次思考中,我能感覺到我正在向一個陌生的地方走去,前途是光是暗也無法推測,我發現我在賭,賭注是一輩子的懊悔或是郁郁終生。
但當我看到陽光彌漫在我身邊時,才發現以前的我是那么幼稚,我始終在找借口或不是借口的借口推卸掉與生俱來的責任,在光怪陸離的現實中找個僻靜的地方希望過云淡風輕的日子。我錯了,我擁有足夠的能力卻不敢恣意妄為,我擁有驚人的天賦卻畏懼這只是南柯一夢,或者這本來就是夢,醒來時卻是了無痕跡和無休止的眷戀。
從前有個同學問我是不是幻想過一些特別的經歷會降臨到自己身上,當時我只笑了笑,卻不知道該怎么回答。
我想我是矛盾的,我認為我的存在與否關系到世間的萬事萬物,但我找不到足夠的證據來證明我具有救世主的身份。因此我一度懷疑過我是不是生不逢時,或是天妒英才。
我在一次次輪回中等待著一個機會,也許是亂世,也許是太平,我沒有所謂的一技之長,只有飛揚跋扈的驕傲和潮洗潮卷的胸懷。只有一笑置之的孤傲和白云蒼狗的方式。我想我不該妄自菲薄,甚至這是理所當然的不加半點修飾的順其自然。
我很喜歡這樣一句話:如果我將庸碌一生的話,地球將停止轉動,地球停止轉動了嗎?沒有,那我將不會庸碌一生。
在特定的時間,特定的環境,特定的地點,有個特定的人將主宰萬事萬物!天生我才必有用!經典的心照不宣,只可惜他的傲慢卻沒有足夠的能力做基墊。
我想我是對的,注定的便是永遠無法改變的,過去的只是匆匆一瞥,將來的只是白駒過隙,一次次的輪回換來的是麻木的循規蹈矩,所以世界需要那么一個人----改變。
分割線-----------------------------------------------------------------------
高中和大學很喜歡文學,特別是在大學期間,在任何填寫個人資料興趣愛好一欄中填寫的都是文學和編程,這就好比我的左手和右手,缺一不可。
好了言歸正傳,來說說Qt編寫可換膚的中文拼音輸入法。在ARM上,如果采用QT開發應用程序,基本上都會遇到一個問題,需要在應用程序中輸入漢字,這個就比較麻煩,就算接了實體鍵盤,也只能輸入字母和數字的,對中文無可奈何,為此就需要用QT自己來實現一個。
百度一搜索,有很多前輩都寫過類似的輸入法,但是基本上都是用QWSInputMethod相關的機制,我覺得這樣有點不妥,絕大部分界面丑陋,只支持單個漢字輸入,而且基本上不支持實體鍵盤和虛擬鍵盤同步輸入。?
運行截圖:
?
?
?
?
?
?
?
?
?
?
特點:
1:各Qt版本(Qt4.6-Qt5.4)、各操作系統(windows、linux、嵌入式linux-ARM)全編譯運行通過,界面一致。
2:支持小寫、大寫、中文三種模式輸入,自由切換。
3:支持單拼雙拼詞組輸入,網上大部分只支持單個漢字輸入。
4:智能分頁算法,可任意翻頁查看漢字詞組。
5:除了支持鼠標單擊軟鍵盤輸入外,還支持實體鍵盤同步輸入,代碼中有映射處理,對應實體鍵盤的按鍵會反應到軟鍵盤處理。
6:七套精美皮膚樣式選擇,鼠標右鍵任意換膚。
7:代碼優化到極致,包括注釋和所有完善性代碼處理總共不到500行。
8:除了可以單擊軟鍵盤和實體鍵盤上的數字來選擇對應的漢字外,還支持鼠標單擊漢字顯示處來選擇漢字。
9:無邊框窗體,可拖動移動。
10:sqlite數據庫存儲漢字字庫,可自由添加自定義的詞組。
11:參考實體鍵盤布局,更逼真。
12:界面布局、字庫算法、界面切換100%首創處理,與任何網上的Qt輸入法處理方式和布局截然不同。
核心方法:
1:獲取當前焦點控件。
Qt封裝了一個focusChanged信號,提供兩個參數QWidget?*oldWidget,?QWidget?*nowWidget,這樣就給輸入法的處理帶來了極大的方便。
//綁定全局改變焦點信號槽connect(qApp,?SIGNAL(focusChanged(QWidget?*,?QWidget?*)),
????????????this,?SLOT(focusChanged(QWidget?*,?QWidget?*)));
void?frmInput::focusChanged(QWidget?*oldWidget,?QWidget?*nowWidget)
{
????//qDebug()?<<?"oldWidget:"?<<?oldWidget?<<?"nowWidget:"?<<?nowWidget;
????if?(nowWidget?!=?0?&&?!this->isAncestorOf(nowWidget))?{
????????if?(nowWidget->inherits("QLineEdit"))?{
????????????currentLineEdit?=?(QLineEdit?*)nowWidget;
????????????this->setVisible(true);
????????}?else?{
????????????currentLineEdit?=?0;
????????????this->setVisible(false);
????????????//需要將輸入法切換到最初的原始狀態--小寫
????????????currentType="min";
????????????changeType(currentType);
????????}
????}
}
2:小寫、大寫、中文三種模式切換。
void?frmInput::changeType(QString?type){
????if?(type?==?"max")?{
????????changeLetter(true);
????????ui->btnType->setText("大寫");
????????ui->widgetTop->setVisible(false);
????????this->setGeometry(this->geometry().x(),?this->geometry().y(),?550,?160);
????}?else?if?(type?==?"min")?{
????????changeLetter(false);
????????ui->btnType->setText("小寫");
????????ui->widgetTop->setVisible(false);
????????this->setGeometry(this->geometry().x(),?this->geometry().y(),?550,?160);
????}?else?{
????????changeLetter(false);
????????ui->btnType->setText("中文");
????????ui->widgetTop->setVisible(true);
????????this->setGeometry(this->geometry().x(),?this->geometry().y(),?550,?215);
????????//每次切換到中文顯示,都要執行清空之前中文模式下的信息
????????clearChinese();
????????ui->labPY->setText("");
????}
}
void?frmInput::changeLetter(bool?isUpper)
{
????QList<QPushButton?*>?btn?=?this->findChildren<QPushButton?*>();
????foreach?(QPushButton?*?b,?btn)?{
????????if?(b->property("btnLetter").toBool())?{
????????????if?(isUpper)?{
????????????????b->setText(b->text().toUpper());
????????????}?else?{
????????????????b->setText(b->text().toLower());
????????????}
????????}
????}
}
3:軟鍵盤按鈕單擊事件處理。
void?frmInput::btn_clicked(){
????QPushButton?*btn?=?(QPushButton?*)sender();
????QString?objectName?=?btn->objectName();
????if?(objectName?==?"btnType")?{
????????if?(currentType?==?"min")?{
????????????currentType?=?"max";
????????}?else?if?(currentType?==?"max")?{
????????????currentType?=?"chinese";
????????}?else?if?(currentType?==?"chinese")?{
????????????currentType?=?"min";
????????}
????????changeType(currentType);
????}?else?if?(objectName?==?"btnDelete"?||?objectName?==?"btnDeleteMin")?{
????????//如果當前是中文模式,則刪除對應拼音,刪除完拼音之后再刪除對應文本輸入框的內容
????????if?(currentType?==?"chinese")?{
????????????QString?txt?=?ui->labPY->text();
????????????int?len?=?txt.length();
????????????if?(len?>?0)?{
????????????????ui->labPY->setText(txt.left(len?-?1));
????????????????selectChinese();
????????????}?else?{
????????????????if?(currentLineEdit?!=?0)?{
????????????????????currentLineEdit->backspace();
????????????????}
????????????}
????????}?else?{
????????????if?(currentLineEdit?!=?0)?{
????????????????currentLineEdit->backspace();
????????????}
????????}
????}?else?if?(objectName?==?"btnPre")?{
????????if?(currentPY_index?>=?20)?{
????????????if?(currentPY_index?%?10?==?0)?{
????????????????currentPY_index?-=?20;
????????????}?else?{
????????????????currentPY_index?=?currentPY_count?-?(currentPY_count?%?10)?-?10;
????????????}
????????}?else?{
????????????currentPY_index?=?0;
????????}
????????showChinese();
????}?else?if?(objectName?==?"btnNext")?{
????????if?(currentPY_index?<?currentPY_count?-?1)?{
????????????showChinese();
????????}
????}?else?{
????????QString?value?=?btn->text();
????????//如果是&按鈕,因為對應&被過濾,所以真實的text為去除前面一個&字符
????????if?(objectName?==?"btnOther7")?{
????????????value?=?value.right(1);
????????}
????????//當前不是中文模式,則單擊按鈕對應text為傳遞參數
????????if?(currentType?!=?"chinese")?{
????????????if?(currentLineEdit?!=?0)?{
????????????????currentLineEdit->insert(value);
????????????}
????????}?else?{
????????????if?(currentLineEdit?!=?0)?{
????????????????//中文模式下,不允許輸入特殊字符,單擊對應數字按鍵取得當前索引的漢字
????????????????if?(btn->property("btnOther").toBool())?{
????????????????????if?(ui->labPY->text().length()?==?0)?{
????????????????????????currentLineEdit->insert(value);
????????????????????}
????????????????}?else?if?(btn->property("btnNum").toBool())?{
????????????????????if?(ui->labPY->text().length()?==?0)?{
????????????????????????currentLineEdit->insert(value);
????????????????????}?else?if?(objectName?==?"btn0")?{
????????????????????????setChinese(0);
????????????????????}?else?if?(objectName?==?"btn1")?{
????????????????????????setChinese(1);
????????????????????}?else?if?(objectName?==?"btn2")?{
????????????????????????setChinese(2);
????????????????????}?else?if?(objectName?==?"btn3")?{
????????????????????????setChinese(3);
????????????????????}?else?if?(objectName?==?"btn4")?{
????????????????????????setChinese(4);
????????????????????}?else?if?(objectName?==?"btn5")?{
????????????????????????setChinese(5);
????????????????????}?else?if?(objectName?==?"btn6")?{
????????????????????????setChinese(6);
????????????????????}?else?if?(objectName?==?"btn7")?{
????????????????????????setChinese(7);
????????????????????}?else?if?(objectName?==?"btn8")?{
????????????????????????setChinese(8);
????????????????????}?else?if?(objectName?==?"btn9")?{
????????????????????????setChinese(9);
????????????????????}
????????????????}?else?if?(btn->property("btnLetter").toBool())?{
????????????????????ui->labPY->setText(ui->labPY->text()?+?value);
????????????????????selectChinese();
????????????????}
????????????}
????????}
????}
}
4:漢字列表單擊選擇。
//事件過濾器,用于識別鼠標單擊漢字標簽處獲取對應漢字bool?frmInput::eventFilter(QObject?*obj,?QEvent?*event)
{
????if?(event->type()?==?QEvent::MouseButtonPress)?{
????????if?(obj?==?ui->labCh0)?{
????????????setChinese(0);
????????}?else?if?(obj?==?ui->labCh1)?{
????????????setChinese(1);
????????}?else?if?(obj?==?ui->labCh2)?{
????????????setChinese(2);
????????}?else?if?(obj?==?ui->labCh3)?{
????????????setChinese(3);
????????}?else?if?(obj?==?ui->labCh4)?{
????????????setChinese(4);
????????}?else?if?(obj?==?ui->labCh5)?{
????????????setChinese(5);
????????}?else?if?(obj?==?ui->labCh6)?{
????????????setChinese(6);
????????}?else?if?(obj?==?ui->labCh7)?{
????????????setChinese(7);
????????}?else?if?(obj?==?ui->labCh8)?{
????????????setChinese(8);
????????}?else?if?(obj?==?ui->labCh9)?{
????????????setChinese(9);
????????}
????????return?false;
????}?else?if?(event->type()?==?QEvent::KeyPress)?{
????????//如果處于中文模式,需要將當前按鍵對應反應到輸入法界面上
????????if?(currentType?==?"chinese")?{
????????????QKeyEvent?*keyEvent?=?static_cast<QKeyEvent?*>(event);
????????????if?(keyEvent->key()?==?Qt::Key_Backspace)?{
????????????????ui->btnDelete->click();
????????????}?else?{
????????????????QString?key?=?keyEvent->text();
????????????????QList<QPushButton?*>?btn?=?this->findChildren<QPushButton?*>();
????????????????foreach?(QPushButton?*?b,?btn)?{
????????????????????if?(b->text()?==?key)?{
????????????????????????b->click();
????????????????????????break;
????????????????????}
????????????????}
????????????}
????????????return?true;
????????}
????????return?false;
????}
????return?QObject::eventFilter(obj,?event);
}
5:漢字智能分頁算法。
void?frmInput::selectChinese(){
????clearChinese();
????QSqlQuery?query;
????QString?currentPY?=?ui->labPY->text();
????QString?sql?=?"select?[word]?from?[pinyin]?where?[pinyin]='"?+?currentPY?+?"';";
????query.exec(sql);
????//逐個將查詢到的字詞加入漢字隊列
????while(query.next())?{
????????QString?result?=?query.value(0).toString();
????????if?(App::PYType?==?"danpin")?{
????????????allPY.append(result);
????????????currentPY_count++;
????????}?else?{
????????????QStringList?text?=?result.split("?");
????????????foreach?(QString?txt,?text)?{
????????????????if?(txt.length()?>?0)?{
????????????????????allPY.append(txt);
????????????????????currentPY_count++;
????????????????}
????????????}
????????}
????}
????showChinese();
}
void?frmInput::showChinese()
{
????//每個版面最多顯示10個漢字
????int?count?=?0;
????currentPY.clear();
????for?(int?i?=?0;?i?<?10;?i++)?{
????????labCh[i]->setText("");
????}
?
????for?(int?i?=?currentPY_index;?i?<?currentPY_count;?i++)?{
????????if?(count?==?10)?{
????????????break;
????????}
????????QString?txt?=?QString("%1.%2").arg(count).arg(allPY[currentPY_index]);
????????currentPY.append(allPY[currentPY_index]);
????????labCh[count]->setText(txt);
????????count++;
????????currentPY_index++;
????}
????//qDebug()?<<?"currentPY_index:"?<<?currentPY_index?<<?"currentPY_count:"?<<?currentPY_count;
}
?
可定制皮膚樣式和輸入法布局,聯系QQ:517216493
可執行文件下載地址:http://pan.baidu.com/s/1sjHPM8l
核心代碼下載地址:http://pan.baidu.com/s/1hqu16M4
備注:
核心代碼開源,希望大家嘴下留情,10元出售完整工程,歡迎大家多多提建議!
謝謝!
編譯完成后將源碼下的file目錄中的兩個數據庫文件復制到bin目錄即可。
總結
以上是生活随笔為你收集整理的Qt编写可换肤的中文双拼汉字输入法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用SQLCMD在SQLServer执行
- 下一篇: zabbix—安装agent客户端(li