Qt -- 输入法插件

Qt应用启动之前会根据环境变量QT_IM_MODULE的值加载匹配的输入法插件,此过程可简单理解为:

  1. Qt扫描QT_INSTALL/plugins/platforminputcontexts/路径下的.dll文件,并尝试加载
  2. 得到插件中实现了QPlatformInputContextPlugin类的实例
  3. 调用步骤2中实例的create方法,create的传入参数key为QT_IM_MODULE的值,如果该值与此插件所定义的值相匹配则生成QPlatformInputContext对象
    QPlatformInputContext对象即为输入法上下文对象,相当于输入法的入口。不过具体到实际开发中,我们是定义一个QPlatformInputContext的子类来实现自定义的输入法。
    Qt输入法的工作原理可描述为
  4. QWidget得到焦点
  5. Qt框架将该事件告知输入法上下文对象
  6. 输入法上下文对象查看有焦点对象的类型,如果需要弹出输入窗口,则将自身设置为有焦点对象的事件过滤器并根据有焦点对象的位置显示出输入法面板
  7. 根据需要,拦截发送给有焦点对象的相关按键事件,根据键值从输入法引擎中取得结果字符串。
  8. 在适当时间点(比如检测到按回车键)将结果字符串发送给有焦点对象实现。
  9. 如果焦点切换到其他非可输入Widget,会触发输入法上下文对象的QPlatformInputContext的hideInputPanel方法,自定义输入法类只需重载该方法即可知道何时隐藏输入法面板


    Qt 工程示例
    .pro

QT  += widgets  gui-private


TARGET  = demoinputcontextplugin
TEMPLATE   = lib



PLUGIN_TYPE  = platforminputcontexts
PLUGIN_CLASS_NAME = DemoPlatformInputContextPlugin

HEADERS += \
    PlatformInputContext.h \
    main.h

SOURCES += \
    PlatformInputContext.cpp \
    main.cpp

DISTFILES += \
    demoim.json

输入法上下文子类

/** 
 * \file PlatformInputContext.h
 */
#ifndef PLATFORMINPUTCONTEXT_H
#define PLATFORMINPUTCONTEXT_H

#include <qpa/qplatforminputcontext.h>
#include <QPointer>

class PlatformInputContext : public QPlatformInputContext
{
    Q_OBJECT
public:
    explicit PlatformInputContext();
    ~PlatformInputContext();

    virtual bool isValid() const;
    virtual void setFocusObject(QObject *object);
    virtual bool eventFilter(QObject * watched, QEvent *event);

    virtual void showInputPanel();
    virtual void hideInputPanel();

private:
    QPointer<QObject>  m_focusedObject;
};

#endif // PLATFORMINPUTCONTEXT_H
/**
 * \file PlatformInputContext.cpp
 * 
 * \brief 输入法上下文实现类
 */ 
#include "PlatformInputContext.h"
#include <QDebug>

PlatformInputContext::PlatformInputContext()
{

}


PlatformInputContext::~PlatformInputContext()
{

}

bool PlatformInputContext::isValid() const
{
    qDebug() << "isValid";
    return true;
}


void PlatformInputContext::setFocusObject(QObject *object)
{
    Q_UNUSED(object);

    if(object)
        qDebug() << "setFocusObject" << object->objectName();

    if(m_focusedObject){
        m_focusedObject->removeEventFilter(this);
    }

    m_focusedObject  = object;

    if(m_focusedObject){
        // 查询是否有焦点控件是否需要输入法
        QInputMethodQueryEvent imEvent(Qt::ImQueryInput | Qt::ImEnabled);
        QGuiApplication::sendEvent(m_focusedObject, &imEvent);
        bool isImEnabled  = imEvent.value(Qt::ImEnabled).toBool();
        if(isImEnabled){
            qDebug() << "Some gay need input method";
            m_focusedObject->installEventFilter(this);
        }
    }
}


bool PlatformInputContext::eventFilter(QObject *watched, QEvent *event)
{
    Q_UNUSED(watched);
    Q_UNUSED(event);
}


void PlatformInputContext::showInputPanel()
{
    qDebug() << "showInputPanel";
}


void PlatformInputContext::hideInputPanel()
{
    qDebug() << "hideInputPanel";
}

生成输入法实例的插件接口(相当于该.dll的“main”)

/**
 * \file main.cpp
 * 
 * \brief 插件实现接口,实例化QPlatformInputContext
 */

#include <qpa/qplatforminputcontextplugin_p.h>
#include "PlatformInputContext.h"
#include <QDebug>

static const char pluginName[]  = "demoim";


class DemoPlatformInputContextPlugin : public QPlatformInputContextPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "demoim.json")

public:
    QStringList keys() const;
    QPlatformInputContext  * create(const QString &key, const QStringList &paramList);
};



QStringList DemoPlatformInputContextPlugin::keys() const
{
    return QStringList(QLatin1String(pluginName));
}


QPlatformInputContext *DemoPlatformInputContextPlugin::create(const QString &key, const QStringList &paramList)
{
    Q_UNUSED(paramList);

    if(key.compare(key, QLatin1String(pluginName), Qt::CaseInsensitive) == 0){
        qDebug() << "Create Demo platform input context";
        PlatformInputContext *  pic  = new PlatformInputContext();
        return pic;
    }

    return 0;
}


#include "main.moc"   /// 这一行没有深究,少了可能无法成功加载输入法

main.cpp中最有一行

#include "main.moc"

还未深究,以俟夫观大牛者得焉


将上述工程构建生成的demoinputcontextplugin.dll复制到QT_INSTALL/plugins/platforminputcontexts/路径下。
新建QApplication工程。在QApplication a(arc, arvc)之前设置环境变量

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    qputenv("QT_IM_MODULE", "demoim");

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
野火开发板是一款基于ARM架构的嵌入式硬件开发板,它通常被用于嵌入式系统的开发和应用。而QT是一款跨平台的应用框架,可以开发出图形界面友好、功能强大的应用程序。 在野火开发板上使用QT开发应用时,可以通过添加输入法插件来实现多语言输入的功能。输入法插件QT的一部分,它可以实现在QT应用程序中使用多种语言的输入法。 对于野火开发板而言,首先要确保QT已成功安装在开发板上。接下来,我们需要为野火开发板添加一个输入法插件。要添加插件,需要通过QT插件系统进行操作。 首先,在开发板上找到QT的安装目录,通常默认为/opt目录。然后,在QT安装目录下找到plugins目录。在plugins目录中,可以找到一个叫platforminputcontexts的文件夹,该文件夹存放着QT输入法插件。 在插件目录中,可以选择已有的输入法插件文件(例如中文输入法插件libfcitxplatforminputcontextplugin.so),将其复制到开发板的QT插件目录中。 插件复制完成后,需要在QT应用程序中进行相应的配置,使其能够加载该输入法插件。具体的配置方法可以参考QT的官方文档或者开发板的使用手册。 完成以上步骤后,在QT应用程序中即可使用添加的输入法插件,实现中文输入的功能。 总结而言,为野火开发板添加QT输入法插件需要进行几个主要步骤:确认QT已安装在开发板上、找到并复制所需的输入法插件文件、进行相关配置以使插件生效。通过这些步骤,就能够在野火开发板的QT应用程序中使用中文输入法插件
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值