qt输入法设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在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 输入法的工作原理其实就是这么简单!。