我正在将现有的QML / C ++应用程序移植到Android系统。该应用程序已在Android平板电脑上运行,但我遇到Android键盘问题。
由于我的QML / C ++应用程序已经实现了自己的键盘,我想禁用Android。
我尝试在AndroidManifest.xml文件中添加android:windowSoftInputMode="stateAlwaysHidden"
行,但是当我按下编辑框时仍然会出现键盘。
由于我正在移植现有的应用程序,因此我不想编辑应用程序本身的代码。我可以编辑的唯一内容是AndroidManifest.xml,QtApplication.java和QtActivity.java文件。 QtApplication
和QtActivity
来自Application
和Activity
个Android类。
是否可以在应用程序启动时为整个应用程序全局禁用Android键盘(使用编辑清单文件或覆盖onCreate
,onStart
或类似功能)?
Application
和Activity
类中是否有任何函数可以覆盖它们并因此禁用本机键盘?
答案 0 :(得分:3)
一段时间后我找到了一个解决方案,实际上解决了这个问题。我们的想法是使用一个请求软件输入面板(QEvent::RequestSoftwareInputPanel
)的事件。此事件由QML / C ++应用程序发送到主机Android系统。
所以,我实现了一个名为SIPRequestEater的事件过滤器。
class SIPRequestEater: public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::RequestSoftwareInputPanel)
{
// filter out RequestSoftwareInputPanel event
return true;
}
else
{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
};
在调用QCoreApplication
之前,必须将此过滤器安装到QCoreApplication::run
。
QCoreApplication *coreApp = QCoreApplication::instance();
SIPRequestEater *sipRequestEater = new SIPRequestEater();
coreApp->installEventFilter(sipRequestEater);
它也可以安装在QApllication
上。
问题是,此过滤器未捕获QEvent::RequestSoftwareInputPanel
事件。我对此的解释是,与QCoreApplication::installEventFilter(<filter>)
一起安装的过滤器仅适用于从Android到QML应用程序的输入事件。从QML应用程序到Android系统,QEvent::RequestSoftwareInputPanel
实际上正朝着另一个方向发展。我没有发现是否可以过滤/禁用输出事件。因此,我决定过滤掉事件QEvent::FocusIn
中的焦点,这实际上会导致QEvent::RequestSoftwareInputPanel
。对于我们的应用程序,它可以正常工作。 Android键盘不再出现,我们的编辑文本字段仍然得到关注,因为我们有自己的焦点和键盘实现。我相信这对每个人来说都不是完美的解决方案,这也是我称之为解决方法的原因。
如果有人知道,如何过滤输出事件,特别是QEvent::RequestSoftwareInputPanel
,请在此处发布。
过滤器的最终实现是:
class SIPRequestEater: public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::FocusIn)
{
// filter out FocusIn event
return true;
}
else
{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
};
答案 1 :(得分:3)
QApplication :: setAutoSipEnabled(false)禁用软件虚拟键盘自动弹出。您可以使用&#34; Q_OS_ANDROID&#34;预处理程序指令,以避免修改其他目标平台上的行为:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
#ifdef Q_OS_ANDROID
a.setAutoSipEnabled(false);
#endif
(...)
}
您可以使用以下代码以编程方式显示或隐藏虚拟键盘:
QInputMethod* input;
input = QGuiApplication::inputMethod();
if(input->isVisible())
{
input->setVisible(false);
}
else
{
input->setVisible(true);
}
答案 2 :(得分:0)
这是另一种使用 Qt.inputMethod 的方法 - 例如通过在 qml 根项中添加 visibleChanged 处理程序,在虚拟键盘可见时立即隐藏它
Component.onCompleted: {
Qt.inputMethod.visibleChanged.connect(function () {
if (Qt.inputMethod.visible)
Qt.inputMethod.hide()
})
}
通过这种方法,还可以添加用户界面设置来选择要使用的键盘(系统或内置应用)。
更新:
发现有时在隐藏之前可能会出现系统虚拟键盘的闪烁,尤其是在多次点击文本输入字段时。在 C++ 中处理 visibleChanged 不能解决这个问题,但似乎不那么频繁。
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::visibleChanged, [] {
QGuiApplication::inputMethod()->hide();
});