qt 中文输入法

最近使用qt, 苦于没有找到输入法,下了几个版本后,运行也没好的。 要不没有中文,要不直接英文输入都成问题。 于是我就自己用了一些时间,写了输入法。 随着了解的深入, 发现qt输入法有两个接口。 一个是QInputContext。一个是QWSInputMethod。 这两个我的理解是QInputContext 通用些。而且高版本都用这个。 QWSMethod 就是大多应用嵌入式,适用低版本。 在之前先提示下关于中文乱码的问题, 请在创建了QApplication之后调用:

 QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
 QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); 

 

两种输入的使用方法。

QInputContext:

 QInputContext *im = new InputMethod();

 app.setInputContext( im );

 

QWSInputMethod:

 QWSInputMethod *im = new myInput;
 QWSServer::setCurrentInputMethod( im );

 im->updateHandler( QWSInputMethod::FocusIn );
 im->updateHandler( QWSInputMethod::FocusOut );

 

关于这两个输入法的共同点就是 一般为两个部分。 一个部分是你的键盘布局。 一个部分是实现与如上两个类的。 先说说QWSInputMethod这个方法是我主要写的。 因为写在板子商用的。 Qt版本低。

派生QWSInputMethod类。

 

myinput.h

#ifndef MYINPUT_H #define MYINPUT_H

#include <QWSInputMethod> #include "keyboard.h"

class myInput : public QWSInputMethod {  Q_OBJECT

public:  myInput();  ~myInput();    void updateHandler(int type); private:  void updatePosition();

private slots:   void recvChar( QChar c );

private:  KeyBoard *m_ky; };

#endif // MYINPUT_H

myinput.cpp

#include "myinput.h"

myInput::myInput()  : QWSInputMethod() {  m_ky = new KeyBoard;

 connect( m_ky, SIGNAL( characterGenerated( QChar ) ), SLOT( recvChar( QChar ) ) ); }

myInput::~myInput() {  delete m_ky; }

void myInput::updateHandler(int type) {         switch(type)         {         case QWSInputMethod::FocusIn:             {     m_ky->show();     updatePosition();     break;    }         case QWSInputMethod::FocusOut:             {     m_ky->hide();     break;    }         default:             break;         } }

void myInput::updatePosition() {  m_ky->AdjustInputPos(); }

void myInput::recvChar( QChar c ) {  QPointer<QWidget> w = QApplication::focusWidget();  if (!w)   return;

 /* 当收到按键面板的按键输入后,分别向当前焦点Widget发送KeyPress和KeyRelease事件 */

 QKeyEvent keyPress(QEvent::KeyPress, c.unicode(), Qt::NoModifier, QString(c));  QApplication::sendEvent(w, &keyPress);

 if (!w)   return;

 QKeyEvent keyRelease(QEvent::KeyRelease, c.unicode(), Qt::NoModifier, QString(c));  QApplication::sendEvent(w, &keyRelease); }

这个类的代码主要是设置输入法的显示位置。 还有我把输入英文的处理也放在这里的。 主要是好区分。
关于Keyboard代码的。就不贴了,有点多。 Keyboard就包含了键盘布局 (是全键盘哦),处理中文信息。
 
还有个类就是读取中文的。
HanziManage 该类为了少写点文件放在Keyboard里面。 可以自己分开。

class HanziManage{ public:  HanziManage( std::string filename);  ~HanziManage();

 int setHanziPage( std::string key );  int currentPageHanzi( std::vector<std::string > & v );  void pageUp();  void pageDown();

private:  int readFile(std::string filename); private:  std::map< std::string, std::string > m_mapData;  std::multimap< int, std::string >  m_mapPage;  int          m_page_num;  int          m_current_page; } ;

实现部分。

//******************************************************* // //class HanziManage ;  //read hanzi from file;  // //********************************************************

HanziManage::HanziManage( std::string filename )  : m_current_page( 0 ),    m_page_num( 0 ) {  m_mapData.clear();  m_mapPage.clear();

 readFile( filename ); }

HanziManage::~HanziManage() {

}

int HanziManage::readFile(std::string name) {  std::ifstream in( name.c_str() );  if(!in)  {   printf("Can not find %s \n", name.c_str());   return -1;  }  std::string line;  getline( in, line, '\n' );  while(!in.eof())  {   std::string strLine( line );

  std::string::size_type index = 0;   std::string::size_type pos = 0;   if( ( index = strLine.find( ' ',  pos) ) !=  std::string::npos )   {    std::string key = strLine.substr( pos, index );    std::string val = strLine.substr( index + 1 );    m_mapData.insert( std::pair< std::string , std::string >( key, val ) );   }   getline( in, line, '\n' );  }

 return 0; }

int HanziManage::setHanziPage(std::string py ) {  m_mapPage.clear();  m_current_page = 0;  m_page_num = 0;

 std::map<std::string , std::string >::const_iterator iter = m_mapData.find( py );  if( iter == m_mapData.end() )  {   printf( "not find pinyin \n ");   return -1;  }

 std::string strHanzi = iter->second;  std::cout<< strHanzi.c_str() << "\n";

 std::string::size_type index = 0;  std::string::size_type pos = 0;  int pageNum = 0;  while( (index = strHanzi.find( ' ', pos ) ) != std::string::npos )  {   std::string hanzi = strHanzi.substr( pos, index - pos );   m_mapPage.insert( std::pair< int, std::string >( m_page_num, hanzi ) );   ++pageNum;   pos = index + 1;

  if( pageNum % 6 == 0 )   {    ++m_page_num ;   }  }  if( pageNum % 6 == 0 )   --m_page_num;  return 0; }

int HanziManage::currentPageHanzi( std::vector<std::string > & v ) {  if( m_mapPage.empty() )  {   return -1;  }  if( m_current_page > m_page_num )  {   return -1;  }

 typedef std::multimap< int, std::string >::const_iterator mmiter;  std::pair< mmiter, mmiter > iter = m_mapPage.equal_range( m_current_page );    mmiter it = iter.first;  while( it != iter.second )  {   v.push_back( it->second );   ++it;  }

 return v.size(); }

void HanziManage::pageDown( ) {  if( m_current_page >= m_page_num )  {   return ;  }  ++m_current_page; }

void HanziManage::pageUp( ) {  if( m_current_page <= 0 )  {   return ;  }  --m_current_page; }

该类读取中文到map中,然后输入拼音 开始查找所属拼音的汉字。在放进map里,按页存放。 我这里规定每页六个汉字。
之后currentPageHanzi 来获取当页的汉字。 而翻页这是pageUp pageDown.
 
基于 QWSInputMethod的输入法就介绍完了。 关于源代码下面将会发地址。 接下来介绍QInputContext的输入法了 这个Keyboard 与 HanziManage完全相同。直说 实现QInputContext的部分。
 
inputmethod.h

#include "keyboard.h" #include "qinputcontext.h"

class InputMethod:public QInputContext {     Q_OBJECT public:     InputMethod();     ~InputMethod();

    bool eventFilter(QObject *obj, QEvent *event);

 QString identifierName();     QString language();

    void reset();     void update();  bool filterEvent( const QEvent *event );     bool isComposing() const;

public:     KeyBoard *keyboard;

public:     void showKeyBoard();

signals:     void setImObjName(QString); private slots:  void setInputText(QChar c);

};

#endif // INPUTMETHOD_H

 inputmethod.cpp

#include "inputmethod.h" #include "login.h"

InputMethod::InputMethod() {     keyboard = new KeyBoard;  connect( keyboard, SIGNAL( characterGenerated(QChar) ), SLOT(setInputText(QChar ) ) ); }

InputMethod::~InputMethod() {     delete keyboard; }

/* * Name : void eventFilter(QObject *obj, QEvent *event); * Type : QEvent * Func : judge input method event * In   : QObject,QEvent * Out  : bool */ bool InputMethod::eventFilter(QObject *obj, QEvent *event) {     if(event->type()==QEvent::MouseButtonPress)     {         emit setImObjName(obj->objectName());         showKeyBoard();         return true;     }

    return QObject::eventFilter(obj,event); }

/* * Name : void showKeyBoard(); * Type : function * Func : show keyBoard * In   : Null * Out  : Null */ void InputMethod::showKeyBoard() {     keyboard->move(50,120);  keyboard->show(); }

 

void InputMethod::setInputText( QChar c ) {  QPointer<QWidget> w = QApplication::focusWidget();  if (!w)   return;

 /* 当收到按键面板的按键输入后,分别向当前焦点Widget发送KeyPress和KeyRelease事件 */

 QKeyEvent keyPress(QEvent::KeyPress, c.unicode(), Qt::NoModifier, QString(c));  QApplication::sendEvent(w, &keyPress);

 if (!w)   return;

 QKeyEvent keyRelease(QEvent::KeyRelease, c.unicode(), Qt::NoModifier, QString(c));  QApplication::sendEvent(w, &keyRelease); }

QString InputMethod::identifierName() {  return ""; } QString InputMethod::language() {  return ""; }

void InputMethod::reset() { } void InputMethod::update() { }

bool InputMethod::isComposing() const {  return true; }

bool InputMethod::filterEvent( const QEvent *event ) {  if (event->type() == QEvent::RequestSoftwareInputPanel)

 {

  /* 当某个Widget请求软键盘输入时,显示软键盘 */   keyboard->show();   return true;  }

 else if (event->type() == QEvent::CloseSoftwareInputPanel)

 {

  /* 当某个Widget请求关闭软键盘输入时,关闭软键盘 */   keyboard->hide(); //这里源代码里呗注释了 调试的时候,请下载后自行删除注释。   return true;  }  return false;

}

大部分代码已经发出来了。 写qt的输入法赶紧比minigui的输入法好多了。 哈哈 不是贬低哈。 minigui灵活,方便,但是不易用。 qt方便,纯面向对象的。
 
这里再说哈,其实这界面是我下的别人改的。我不想搞界面。没有美术细胞。 
这里感谢哈他。 没有他的界面我也不想搞这输入法。这界面看起来很舒服。我懒得截图了我去掉了图片。因为我现在还板子没得库看不到我就干脆去掉了。 附上这位仁兄的博客:http://blog.csdn.net/tandesir/article/details/7283158
 
别搞错了这个是博客 下载地址在最后
源代码下载地址。 http://download.csdn.net/detail/asb2010/5444121  字库文件是.db文件 该文件格式是ASCII。如果你发现乱码请看该文件格式是否正确。 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值