快速搭建一款输入法(封装输入法引擎)

输入法最核心的是输入法引擎,输入法引擎负责加载和管理输入法配置和输入法的词库,输入法引擎对用户输入的拼音字符串进行处理并返回对应的候选列表。通过引入输入法引擎我们就可以将我们输入法的拼音串转换成对应的中文候选了。

这里我不建议用户自己开发输入法引擎,这个难度还是很大的,涉及到了音节拆分和智能组词等等。如果是简单的使用的话,采用开源的输入法引擎库就行,这里我采用的是谷歌的开源输入法引擎,引擎项目的地址如下:

GitHub - lelelongwang/GooglePinyinIME: Google 拼音输入法

由于谷歌拼音输入法的引擎接口比较多,新手调用起来比较吃力,这里对输入法的引擎进行了简单的封装,封装之后就可以无脑使用了。封装的接口如下:

//pinyin_engline.h
#ifndef _PINYIN_ENGINE_H_
#define _PINYIN_ENGINE_H_

#include <QObject>
class pinyin_engine : public QObject
{
    Q_OBJECT

public:
    explicit pinyin_engine (QObject *parent = 0);
    ~pinyin_engine ();


public:
    /**@brief 初始化输入法引擎
   * @param[in]  dir            词库文件的目录
   * @param[in]  max_spell_len  字符串最长的长度默认64
   * @param[in]  max_output_len 输出中文文本的最长长度
   * @return  函数执行结果
   * - 1  执行成功
   * - 0  执行错误
   */
    bool init(const QString &dir = "", int max_spell_len = 64, int max_output_len = 64);

    /**@brief 关闭输入法引擎
   */
    void deinit();

    /**@brief 清空词库缓存
   */
    void flush_cache();

    /**@brief 通过拼音的拼音字符串查找对应的候选结果
   * @param[in]  search 拼音字符串
   * @return  候选词的个数
   */
    unsigned int search(const QString &spell);

    /**@brief 删除候选拼音串中的音节然后重新获取候选
   * @param[in]  pos 删除音节的位置
   * @return  候选词的个数
   */
    unsigned int del_search(unsigned pos);

    /**@brief 对检索进行重置
   */
    void reset_search();

    /**@brief 查找正在检索的音节的位置
   * @return  对应的位置
   */
    unsigned short cur_search_pos();

    /**@brief 获取固定索引位置的候选词
   * @param[in]  index 候选词索引的位置
   * @return  候选词字符串
   */
    QString get_candidate(unsigned int index);

    /**@brief 选择部分音节的候选词作为部分词
   * @param[in]  index 部分音节的候选词
   * @return  候选词的个数
   */
    unsigned int choose(unsigned int index);

    /**@brief 取消上一次的候选
   * @return  返回取消候选之后的候选词的个数
   */
    unsigned unchoose();

private:
    bool m_enable;      //引擎开关
    int  m_spell_len;   //字符串长度
    int  m_output_len;  //输出字符串的长度
};

#endif 
//pinyin_engline.cpp
#include "pinyin_engine.h"
#include <QApplication>
#include <pinyinime.h>
#include <string.h>

using namespace ime_pinyin;

//系统词库的名称
#define DICT_PATH           "dict_pinyin.dat"

//用户词库的名称
#define DICT_USER_PATH      "dict_pinyin_user.dat"

//最多的汉字的候选个数
#define MAX_SINGLE_ZI 60

static size_t fix_cand_len (size_t cand, int output_len)
{

    size_t i;
    size_t decode_len;
    size_t single = 0;
    size_t multi = 0;
    char16 *cand_buf = new char16[output_len];

    //查找字拼音串中还没有被解析出来的拼音串的长度
    im_get_sps_str(&decode_len);

    //如果只有一个拼音字符的话候选只保留10个
    if (decode_len == 1) {
        if (cand > 10) {
            cand = 10;
        }
        delete cand_buf;
        return  cand;
    }

    for (i = 0; i < cand; i++) {
        //查找满足固定长度的候选
        im_get_candidate(i, cand_buf, output_len);

        //候选词的个数
        if (strlen((char *)cand_buf) > 2)
        {
            multi++;
        }
        //候选字的个数
        else
        {
            single++;
            if (single > MAX_SINGLE_ZI) {
                break;
            }
        }
    }

    cand = multi + single;
    delete cand_buf;
    return  cand;
}

pinyin_engine::pinyin_engine(QObject *parent) :
    QObject(parent),m_enable(false)
{
}

pinyin_engine::~pinyin_engine()
{
}

bool pinyin_engine::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() + "/dict";
    }

    //打开用户词库和系统词库
    ret = im_open_decoder(QString("%1/" DICT_PATH).arg(app_dir).toLocal8Bit().data(),
                          QString("%1/" DICT_USER_PATH).arg(app_dir).toLocal8Bit().data());
    m_enable = ret;

    if (ret == false) {
        return ret;
    }
    im_set_max_lens(max_spell_len ,max_output_len);
    reset_search();

    m_spell_len = max_spell_len;
    m_output_len = max_output_len;

    return  ret;
}

void pinyin_engine::deinit()
{
    im_close_decoder();
}

void pinyin_engine::flush_cache()
{
    im_flush_cache();
}


unsigned int pinyin_engine::search(const QString &spell)
{
    if (!m_enable)
    {
        return 0;
    }
    QByteArray bytearray;
    char    *pinyin;

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

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

    cand = fix_cand_len(cand, m_output_len);
    return  (unsigned)cand;
}


unsigned int pinyin_engine::del_search(unsigned pos)
{
    if (!m_enable)
    {
        return 0;
    }
    size_t cand = im_delsearch(pos, false, false);

    cand = fix_cand_len(cand, m_output_len);

    return  (unsigned)cand;
}

void pinyin_engine::reset_search()
{
    if (!m_enable)
    {
        return;
    }
    im_reset_search();
}

unsigned short pinyin_engine::cur_search_pos()
{
    const uint16 *start_pos;
    size_t  pos_len;
    size_t  fixed_len = im_get_fixed_len();

    pos_len = im_get_spl_start_pos(start_pos);
    if (fixed_len <= pos_len) {
        return  (start_pos[fixed_len]);
    }
    return  0;
}

QString pinyin_engine::get_candidate(unsigned int index)
{
    char16 *cand_buf = new char16[m_output_len];
    char16 *cand;
    QString cand_str;

    cand = im_get_candidate(index, cand_buf, m_output_len);
    if (cand) {
        cand_str = QString::fromUtf16(cand);
        if (index == 0) {
            cand_str.remove(0, im_get_fixed_len());
        }
    } else {
        cand_str = "";
    }

    delete cand_buf;
    return cand_str;
}


unsigned int pinyin_engine::choose(unsigned int index)
{
    size_t left;

    left = im_choose(index);

    left = fix_cand_len(left, m_output_len);
    if (left < 1) 
    {
        return  0;
    } else {
        return  (left - 1);
    }
}

unsigned pinyin_engine::unchoose()
{
    size_t cand = im_cancel_last_choice();

    cand = fix_cand_len(cand, m_output_len);

    return  (unsigned)cand;
}

通过封装的接口我们就可以很方便的将用户输入的音节字符串转换成对应的中文候选了,这个功能是输入法的基础,很重要。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在Linux系统上下载一个输入法,你可以按照以下步骤进行操作: 1. 进入系统设置(System Settings)。 2. 找到语言支持(Language Support)选项,并点击进入。 3. 在语言支持界面中,查看已经安装的语言。如果没有中文语言,请点击安装/移除语言(Install/Remove Languages)。 4. 安装中文语言后,打开终端(Terminal)。 5. 在终端中输入以下命令来解决可能遇到的锁定目录问题: ``` sudo rm /var/lib/apt/lists/lock sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/lock* ``` 6. 继续在终端中输入以下命令来配置输入法: ``` ibus-setup ``` 7. 输入法配置界面将会弹出,你可以在输入法选项卡中选择你喜欢的输入方式,并配置你喜欢的快捷键。 8. 通常情况下,IBus图标(一个小键盘)会出现在桌面右上角的任务栏中。如果图标消失了,你可以使用以下命令找回它: ``` ibus-daemon -drx ``` 这样,你就可以在Linux系统上下载并配置一个输入法了。 #### 引用[.reference_title] - *1* *2* [如何在linux系统下安装中文输入法](https://blog.csdn.net/weixin_42309293/article/details/116830277)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [linux安装中文输入法](https://blog.csdn.net/m0_67393157/article/details/126434075)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农飞飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值