QT输入法浅析

在Qte的Client/Server体系结构中,QWSServer类负责管理Qte的Server,监听系统事件,尤其是键盘和鼠标事件。当这些监听的事件发生的时候,server会做出判断,这些事件应该发送给那一个客户端。 如果当前系统安装了输入法,那么键盘和鼠标事件在派发之前,就会先送给输入法,让输入法来做一下判断,看输入法是否会处理这个键盘按键,如果输入法已经处理,就不在继续分发这个事件,否则就会按照原先的事件分发机制继续分发这个事件。也就是说,输入法会在应用程序之前接收到键盘事件。 Qte已经定义了一个输入法基类QWSInputMethod,在这个类中封装了一些基本的输入法函数。我们一起来看看QWSInputMethod类的定义: class QWSInputMethod : public QObject { Q_OBJECT public: QWSInputMethod(); virtual ~QWSInputMethod(); enum UpdateType {Update, FocusIn, FocusOut, Reset, Destroyed}; virtual bool filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat); virtual bool filter(const QPoint &, int state, int wheel); virtual void reset(); virtual void updateHandler(int type); virtual void mouseHandler(int pos, int state); virtual void queryResponse(int property, const QVariant&); protected: uint setInputResolution(bool isHigh); uint inputResolutionShift() const; void sendMouseEvent(const QPoint &pos, int state, int wheel); void sendEvent(const QInputMethodEvent*); void sendPreeditString(const QString &preeditString, int cursorPosition, int selectionLength = 0); void sendCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0); void sendQuery(int property); private: bool mIResolution; }; 这个类从QObject类继承而来,定义了 Q_OBJECT 宏,说明这个类支持Qt对象模型的操作,signal/slot,property,都没有问题,这里最关键的几个函数有,两个重载的filter函数,一个用来过滤键盘事件,另一个用来过滤鼠标事件,sendEvent函数用来发送输入法事件,在这个事件中可以打包preedit string, commit string,它还有一个list,可以添加任意多的其它数据。sendPreeditString函数用来把正在输入过程中的字符串发送到当前编辑窗口,而sendCommitString则用来把最终的用户选择的字符串发送到当前编辑窗口。 QWSServer类提供了一个函数来安装输入法,void setCurrentInputMethod ( QWSInputMethod * method),这个函数的参数就是一个QWSInputMethod类的指针。QWSServer是如何管理QWSInputMethod的呢?在 Server端,定义了这么几个变量, static QWSInputMethod *current_IM = 0; static QWSWindow *current_IM_composing_win = 0; static int current_IM_winId = -1; static bool force_reject_strokeIM = false; 其中,最重要的就是current_IM了,这个指针指向当前安装的输入法对象,它就是在QWSServer::setCurrentInputMethod函数中赋值的。 这里是QWSServer::setCurrentInputMethod这个函数的源代码: void QWSServer::setCurrentInputMethod(QWSInputMethod *im) { if (current_IM) current_IM->reset(); current_IM = im; } 再看看这个键盘事件处理函数: void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat) { //……………………….. #ifndef QT_NO_QWS_INPUTMETHODS if (!current_IM || !current_IM->filter(unicode, keycode, modifiers, isPress, autoRepeat)) QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat); #else QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat); #endif } 在QWSServer::sendKeyEvent函数中,会去检查当前是否安装了输入法,如果是,就会去调用这个输入法的filter函数来过滤键盘事件,如果这个函数返回值为true,就不在继续分发这个key事件。 再看看这个鼠标事件处理函数: void QWSServer::sendMouseEvent(const QPoint& pos, int state, int wheel) { // ————————– const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton; int stroke_count; // number of strokes to keep shown. if (force_reject_strokeIM || !current_IM) { stroke_count = 0; } else { stroke_count = current_IM->filter(tpos, state, wheel); } } 在 QWSServer::sendMouseEvent 函数里面,同样会去检查当前是否安装了输入法,如果是,就会去调用输入法的filter函数来过滤鼠标事件,如果这个函数返回值为true,就不在继续分发这个key事件。 看,Qt/Embedded 输入法的工作原理其实就是这么简单!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值