Qt模块扩展:将Qt虚拟键盘的拼音输入法扩展,支持键盘硬件输入的输入法方法(QtVirtualkeyboard)
QtVirtualkeyboard是一个Qt官方给触摸屏提供的Qt应用专用的 (只支持Qt应用程序唤出)输入法解决方案。他支持中文(拼英、手写、仓吉等)、日文、韩文文字的联想词、自动补全等操作,且中文拼英输入法也比较全面好用,可移植性高。可是没有对物理键盘的输入加以支持,导致在研发过程中,如果某些需要对外接物理键盘进行支持,则需要额外的成本加入第三方输入法,十分麻烦且风险巨大。
在这里介绍一种方法,可以让它支持物理键盘输入。
我先通过修改
QVirtualKeyboardInputContextPrivate::filterEvent 函数,增加新的过滤物理键盘事件的方式。这样我们可以监听得到想要的物理键盘事件,比如它自身就支持的上下左右导航键的代码如下:
#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
int key = keyEvent->key();
if ((key >= Qt::Key_Left && key <= Qt::Key_Down) || key == Qt::Key_Return) {
if (type == QEvent::KeyPress && platformInputContext->isInputPanelVisible()) {
activeNavigationKeys += key;
emit navigationKeyPressed(key, keyEvent->isAutoRepeat());
return true;
} else if (type == QEvent::KeyRelease && activeNavigationKeys.contains(key)) {
activeNavigationKeys -= key;
emit navigationKeyReleased(key, keyEvent->isAutoRepeat());
return true;
}
}
#endif
我们可以照搬它的实现,在下面实现一个过滤物理键盘事件的过程
#ifdef QT_VIRTUALKEYBOARD_FILTER_HARDWARE_KEY
int keycode = keyEvent->key();
{
Q_Q(QVirtualKeyboardInputContext);
HKeyState state = (type == QEvent::KeyRelease ? HKeyState::HKeyRelease : HKeyState::HKeyOther);
if(state == HKeyState::HKeyOther)state = (type == QEvent::KeyPress ? HKeyState::HKeyPress : HKeyState::HKeyOther);
bool reval = (emit q->hardKeyBoardChanged(keycode , state));
return reval;
}
#else
// Break composing text since the virtual keyboard does not support hard keyboard events (! now supperted (●'◡'●))
if (!preeditText.isEmpty())
commit();
#endif
通过自定一个 hardKeyBoardChanged 信号来触发物理键盘信号,再通过修改每个不同输入法reset方法来监听该事件,达到每个不同输入法获取不同键盘事件又不影响其他功能的目的。
比如我修改了pinyininputmethod.cpp的reset
if(inputContext())
{
connect(inputContext(), &QVirtualKeyboardInputContext::hardKeyBoardChanged, this, [&](qint32 keycode, qint32 keystate)
{
Q_D(PinyinInputMethod);
if(d->inputMode != QVirtualKeyboardInputEngine::InputMode::Pinyin
|| !inputContext()
|| (keycode >= Qt::Key_Left && keycode <= Qt::Key_Down) // nav key
)
return false;
if(keycode == Qt::Key_Backspace || keycode == Qt::Key_Delete || keycode == Qt::Key_Space)
return keyEvent(static_cast<Qt::Key>(keycode), QString(QChar(keycode)).toLower(), Qt::NoModifier );
if( keystate == HKeyRelease )
{
d->activeHardwareKeys -= keycode;
}
else if( keystate == HKeyPress )
{
if(!d->activeHardwareKeys.contains(keycode))
{
QString text = QString(QChar(keycode)).toLower();
d->activeHardwareKeys += keycode;
bool reval = keyEvent(static_cast<Qt::Key>(keycode), text, Qt::NoModifier );
return reval;
}
}
return true;
}, Qt::UniqueConnection );
}
这样就可以传递物理键盘的点击事件到输入法代码中,并进行输入法的自动联想词等一系列的处理,达到我们让QtVirtualkeyboard变成一个全功能的输入法的目的了。
根据GPL情况,github地址: