Inside Qt Series (十五):Qt/e IME,How it works?

來源:互聯網
上載者:User

前面我們介紹了QteIME的基本設計思路,以及一個最簡單的例子,那麼,Qte的IME是如何工作的呢?本節我們就來看一下Qte的原始碼,一起來解開這個謎團。

在Qte的Client/Server體繫結構中,QWSServer類負責管理Qte的Server,監聽系統事件,尤其是鍵盤和滑鼠事件。當這些監聽的事件發生的時候,server會做出判斷,這些事件應該發送給那一個用戶端。

如果當前系統安裝了IME,那麼鍵盤和滑鼠事件在派發之前,就會先送給IME,讓IME來做一下判斷,看IME是否會處理這個鍵盤按鍵,如果IME已經處理,就不在繼續分發這個事件,否則就會按照原先的事件分發機制繼續分發這個事件。也就是說,IME會在應用程式之前接收到鍵盤事件。

Qte已經定義了一個IME基類QWSInputMethod,在這個類中封裝了一些基本的IME函數。我們一起來看看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函數用來發送IME事件,在這個事件中可以打包preedit string, commit string,它還有一個list,可以添加任意多的其它資料。sendPreeditString函數用來把正在輸入過程中的字串發送到當前編輯視窗,而sendCommitString則用來把最終的使用者選擇的字串發送到當前編輯視窗。

QWSServer類提供了一個函數來安裝IME,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了,這個指標指向當前安裝的IME對象,它就是在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函數中,會去檢查當前是否安裝了IME,如果是,就會去調用這個IME的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 函數裡面,同樣會去檢查當前是否安裝了IME,如果是,就會去調用IME的filter函數來過濾滑鼠事件,如果這個函數傳回值為true,就不在繼續分發這個key事件。

看,Qt/Embedded IME的工作原理其實就是這麼簡單!

下面以一張簡單的UML sequence圖來說明一下:

======================================================================
聲明:
《Inside Qt Series》專欄文章是(http://www.qkevin.com)原創技術文章。
本系列專欄文章可隨意轉載,但必須保留本段聲明和每一篇文章的原始地址。
作者保留著作權,未經作者同意,不得用於任何商業用途

《Inside Qt Series》專欄文章總索引: http://www.qkevin.com/qt
本文原始地址:http://www.qkevin.com/archives/106

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.