由于项目需要用到QT软键盘,本来PC上QT用的5.4.1版本,但不支持QInputContext。所以用了和开发板一样的4.8.5.
1.简单的数字软件盘
在QtEmbedded-4.8.5-arm/examples/tools/inputpanel下面有例子,下面说一下修改;
1).增加退格键,因为键值问题,需要使用quint32,才能生效,把下面的改一下就好;
myinputpanel.cpp
form.panelButton_backspace->setProperty("buttonValue", QVariant(quint32(Qt::Key_Backspace))); //设置退格键 void MyInputPanel::buttonClicked(QWidget *w) { quint32 chr = qvariant_cast<quint32>(w->property("buttonValue")); emit characterGenerated(chr); }
myinputpanelcontext.cpp
connect(inputPanel, SIGNAL(characterGenerated(quint32)), this,SLOT(sendCharacter(quint32))); void MyInputPanelContext::sendCharacter(quint32 character) { QPointer<QWidget> w = focusWidget(); if (!w) return; QKeyEvent keyPress(QEvent::KeyPress,(quint32) character, Qt::NoModifier, QString(character)); QApplication::sendEvent(w, &keyPress); if (!w) return; QKeyEvent keyRelease(QEvent::KeyRelease,(quint32)character, Qt::NoModifier, QString()); //character.unicode() QApplication::sendEvent(w, &keyRelease); }
注意把第二次KeyPress,改为KeyRelease,否则退格键会触发2次
2).鼠标单击弹出软件盘
在myinputpanelcontext.h中增加
class MyProxyStyle : public QProxyStyle { public: int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const { if ( hint == QStyle::SH_RequestSoftwareInputPanel ) return QStyle::RSIP_OnMouseClick; return QProxyStyle::styleHint(hint, option, widget, returnData); } };
在main函数中增加
a.setStyle(new MyProxyStyle);
好了,到这儿我们就拥有一个简单的能输入数字的软键盘
2.SYSZUXpinyin需要修改的地方(移植过程不再赘述)
1)乱码
可以将编码设置为GB2312,或者将字库转码(SYSZUXpinyin/syszux/)
iconv -f gb2312 -t utf-8 syszuxpinyin> syszuxpinyin.tmp
vi一下看syszuxpinyin.tmp中文是否正常,然后覆盖掉原来的
在main函数中加入:
QTextCodec *codec = QTextCodec::codecForName("UTF-8"); //“UTF-8GB2312” QTextCodec::setCodecForLocale(codec); // QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); // QFont font("unifont",6); //a.setFont(font);
注意不要设CStrings,否则输入法打出来的字乱码(原因自行百度)
2)清除上次输入的内容
syszuxpinyin.cpp 中发送完信号,把输入法的lineEdit清了
229 void SyszuxPinyin::affirmString() 230 { 231 emit sendPinyin(lineEdit_window->text()); 232 lineEdit_window->clear(); //add 233 this->hide(); 234 }
3)获取当前控件中的内容(同时支持QSpinBox等控件)
这个是网友做的,他添加了多种控件,让后通过QApplication::focusWidget();来获取当前焦点控件,使用各控件的方法来获取/设置内容(见源码)
4)多次点击同一控件能连续触发输入法(不切换焦点) (见源码)
网上有重载lineEdit的方法,但支持一种控件,多种不同类型的控件难道都去加一套?
我的想法比较简单,就是输入完内容把当前焦点clearFocus(),这样再次点击就会获取焦点,并调出输入法。
还有一种想法是虚拟出一个控件,输入完内容setFocus(),
由于 QWSServer是专门针对嵌入式的(度娘),所以测试完赶紧先把输入法移了吧
syszuxim.h
#ifndef SYSZUXIM_H #define SYSZUXIM_H #include <QWSInputMethod> #include <QtGui> class SyszuxPinyin; class SyszuxIM:public QWSInputMethod { Q_OBJECT public: SyszuxIM(); ~SyszuxIM(); void updateHandler(int); QLineEdit *le; QSpinBox *sb; QDoubleSpinBox *dsb; QTextEdit *tee; QComboBox *cb; QTimeEdit *tie; QDateEdit *de; QDateTimeEdit *dte; enum WidgetType{LINEEDIT,SPINBOX,DOUBLESPINBOX,TEXTEDIT,COMBOBOX,TIMEEDIT,DATEEDIT,DATETIMEEDIT}; WidgetType type; public slots: void confirmString(QString gemfield); private: SyszuxPinyin* syszuxpinyin; QWidget *current_focus_widget; void focusin(); }; #endif
syszuxim.cpp
#include "syszuxim.h" #include "syszuxpinyin.h" SyszuxIM::SyszuxIM() { le = new QLineEdit; //added by me sb = new QSpinBox; dsb = new QDoubleSpinBox; tee = new QTextEdit; cb = new QComboBox; tie = new QTimeEdit; de = new QDateEdit; dte = new QDateTimeEdit; syszuxpinyin = new SyszuxPinyin(this); current_focus_widget=new QWidget; current_focus_widget = QApplication::focusWidget(); syszuxpinyin->resize(800,480); } SyszuxIM::~SyszuxIM() { syszuxpinyin->deleteLater(); } void SyszuxIM::confirmString(QString gemfield) { if(type == LINEEDIT) { le->setText(gemfield); le->clearFocus(); } else if(type == SPINBOX) { sb->setValue(gemfield.toInt()); sb->clearFocus(); } else if(type == DOUBLESPINBOX) { dsb->setValue(gemfield.toFloat()); dsb->clearFocus(); } else if(type == TEXTEDIT) { tee->setText(gemfield); tee->clearFocus(); } else if(type == COMBOBOX) { if(gemfield.isEmpty()) { sendCommitString(gemfield); cb->clearFocus(); } else { cb->setEditText(gemfield);//可能有问题 cb->clearFocus(); } } else { sendCommitString(gemfield); } } void SyszuxIM::updateHandler(int type) { switch(type) { case QWSInputMethod::FocusIn: focusin(); break; case QWSInputMethod::FocusOut: syszuxpinyin->hide(); break; default: break; } } void SyszuxIM::focusin() { QString str; current_focus_widget = QApplication::focusWidget(); if(qobject_cast<QLineEdit*>(current_focus_widget)) { type = LINEEDIT; le= qobject_cast<QLineEdit*>(current_focus_widget); str = le->text(); } else if(qobject_cast<QSpinBox*>(current_focus_widget)) { type = SPINBOX; sb = qobject_cast<QSpinBox*>(current_focus_widget); str = tr("%1").arg(sb->value()); } else if(qobject_cast<QDoubleSpinBox*>(current_focus_widget)) { type = DOUBLESPINBOX; dsb = qobject_cast<QDoubleSpinBox*>(current_focus_widget); str = tr("%1").arg(dsb->value()); } else if(qobject_cast<QTextEdit*>(current_focus_widget)) { type = TEXTEDIT; tee = qobject_cast<QTextEdit*>(current_focus_widget); str = tee->toPlainText(); } else if(qobject_cast<QComboBox*>(current_focus_widget)) { type = COMBOBOX; cb = qobject_cast<QComboBox*>(current_focus_widget); str = cb->currentText(); str = ""; } else str = ""; syszuxpinyin->show(); syszuxpinyin->lineEdit_window->setText(str); }