qt平台集成google拼音中文输入法

qt自5.7.0版本后自带了qtvirtualkeyboard模块,在示例程序里面用过输入法demo,确实很赞,支持各国语言的输入法,中文输入法集成的google智能拼音,支持模糊拼音输入。很遗憾的是它只能在基于QML的应用平台上使用,在传统的Qt widgets应用上无法使用。

在Qt安装目录下qtvirtualkeyboard模块里面,可以找到google拼音源码,通过它来实现基于google拼音的中文输入法。把3rdparty目录下的pinyin文件夹拷贝到工程目录,并把里面的.h和.cpp文件添加到pinyin.pri模块中:

INCLUDEPATH += \
    $$PWD/share \
    $$PWD/include

SOURCES += \
    $$PWD/share/dictbuilder.cpp \
    $$PWD/share/dictlist.cpp \
    $$PWD/share/dicttrie.cpp \
    $$PWD/share/lpicache.cpp \
    $$PWD/share/matrixsearch.cpp \
    $$PWD/share/mystdlib.cpp \
    $$PWD/share/ngram.cpp \
    $$PWD/share/pinyinime.cpp \
    $$PWD/share/searchutility.cpp \
    $$PWD/share/spellingtable.cpp \
    $$PWD/share/spellingtrie.cpp \
    $$PWD/share/splparser.cpp \
    $$PWD/share/sync.cpp \
    $$PWD/share/userdict.cpp \
    $$PWD/share/utf16char.cpp \
    $$PWD/share/utf16reader.cpp \
    $$PWD/googlepinyin.cpp


HEADERS += \
    $$PWD/include/atomdictbase.h \
    $$PWD/include/dictbuilder.h \
    $$PWD/include/dictdef.h \
    $$PWD/include/dictlist.h \
    $$PWD/include/dicttrie.h \
    $$PWD/include/lpicache.h \
    $$PWD/include/matrixsearch.h \
    $$PWD/include/mystdlib.h \
    $$PWD/include/ngram.h \
    $$PWD/include/pinyinime.h \
    $$PWD/include/searchutility.h \
    $$PWD/include/spellingtable.h \
    $$PWD/include/spellingtrie.h \
    $$PWD/include/splparser.h \
    $$PWD/include/sync.h \
    $$PWD/include/userdict.h \
    $$PWD/include/utf16char.h \
    $$PWD/include/utf16reader.h \
    $$PWD/googlepinyin.h

在pinyin.pri模块添加新的文件googlepinyin.h,googlepinyin.cpp,用来封装google拼音调用接口,关键的接口函数如下:

using namespace ime_pinyin;
#define DICT_PATH           "dict_pinyin.dat"
#define DICT_USER_PATH      "dict_pinyin_user.dat"

// init dict database
bool pinyin_im::init(const QString &dir, int max_spell_len, int max_output_len)
{
    bool  	ret;
    QString app_dir = dir;
    if (app_dir.isEmpty()) {
        app_dir = qApp->applicationDirPath() + "/data";
    }

    ret = im_open_decoder(QString("%1/"DICT_PATH).arg(app_dir).toLocal8Bit().data(),
                          QString("%1/"DICT_USER_PATH).arg(app_dir).toLocal8Bit().data());

    enable = ret;
    if (ret == false) {
        return ret;
    }

    im_set_max_lens(max_spell_len /* input pinyin max len */,
                    max_output_len /* max output Chinese character string len */);

    reset_search();

    spell_len = max_spell_len;
    output_len = max_output_len;

    return  ret;
}

// add a char to search
unsigned pinyin_im::search(const QString &spell)
{
    if (!enable)
    {
        return 0;
    }
    QByteArray bytearray;
    char    *pinyin;

    bytearray = spell.toUtf8();
    pinyin = bytearray.data();
    bytearray.size();

    size_t cand = im_search(pinyin, bytearray.size());

//    if (im_get_fixed_len()) {  // if fixed at least 1, candidate 0(whole line) is not display.
//        cand--;
//    }

    cand = fix_cand_len(cand, output_len);

    return  (unsigned)cand;
}

init()是对google拼音字库文件进行初始化,在data文件下两个重要的文件

dict_pinyin.dat
dict_pinyin_user.dat

需要把包含这两个文件的的文件夹data放置在应用程序目录下。

程序主体实现部分代码:

bool PinYinInputMethod::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QMouseEvent::MouseButtonPress) {
        if (watched->inherits("QPushButton")) {
            QPushButton *btn = (QPushButton *)sender();
            btn = (QPushButton *)watched;
            QString objName = watched->objectName();

            if (objName == "btn_Cn") {
                //shift to En/Cn
            }
            else if (objName == "btn_ABC") {
                //shift to ABC/123
            }
            else if (objName == "btn_Space") {
                m_lineEdit->insert(" ");
            }
            else if (objName == "btn_<--") {
                if (!inputLetters.isEmpty()) {
                    if (inputLetters.size() == 1) {
                        this->clearHistory();
                    }
                    else {
                        inputLetters = inputLetters.left(inputLetters.size() - 1);
                        if (!inputLetters.isEmpty()) {
                            this->searchBegin(inputLetters);
                        }
                        else {
                            m_lineEdit->backspace();
                            this->clearHistory();
                        }
                    }
                }
                else {
                    m_lineEdit->backspace();
                    this->clearHistory();
                }
            }
            else if (objName == "btn_Enter") {
                //shift to enter
            }
            else if (objName == "btn_Shift") {
                //ABC to abc
            }
            else if (objName == "btn_down") {
                if (mStackedWidget->currentWidget() == letterBtnWidget) {
                    if (!hQueryView->dataStrings.isEmpty()) {
                        vQueryView->dataStrings = hQueryView->dataStrings;
                        vQueryView->move(0, 0);
                        vQueryView->update();
                        mStackedWidget->setCurrentWidget(vDragWidget);
                    }
                }
                else {
                    mStackedWidget->setCurrentWidget(letterBtnWidget);
                }
            }
            else {
                inputLetters.append(btn->text());
                this->searchBegin(inputLetters);
            }
        }
    }

    return QWidget::eventFilter(watched, event);
}

void PinYinInputMethod::searchBegin(const QString &keywords)
{
    unsigned int candNum = googlePinyin->search(keywords.toLower());
    hQueryView->dataStrings.clear();

    for (unsigned i = 0; i < candNum; i++) {
        QString str = googlePinyin->get_candidate(i);
        hQueryView->dataStrings.append(str);
    }

    spellLabel->setText(keywords);
    hQueryView->move(0, 0);
    hQueryView->update();
}

功能做得很简单,主要通过searchBegin()函数调用google拼音,基本实现了中文拼音输入演示。

 

qt平台集成google拼音中文输入法_第1张图片

qt平台集成google拼音中文输入法_第2张图片

 

你可能感兴趣的:(Qt)