[英]Disable Android keyboard in qml application
我正在將現有的 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
類中是否有任何函數可以覆蓋它們並因此禁用本機鍵盤?
一段時間后,我找到了解決方案,實際上是解決此問題的方法。 這個想法是使用一個請求軟件輸入面板( 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::run
,必須將此過濾器安裝到QCoreApplication
。
QCoreApplication *coreApp = QCoreApplication::instance();
SIPRequestEater *sipRequestEater = new SIPRequestEater();
coreApp->installEventFilter(sipRequestEater);
它也可以安裝在QApllication
。
問題是,這個過濾器沒有捕獲QEvent::RequestSoftwareInputPanel
事件。 我對此的解釋是,與QCoreApplication::installEventFilter(<filter>)
一起安裝的過濾器僅用於輸入事件的過濾器,從 Android 到 QML 應用程序。 QEvent::RequestSoftwareInputPanel
實際上是在走向另一個方向,從 QML 應用程序到 Android 系統。 我不知道是否可以過濾/禁用輸出事件。 正因為如此,我決定過濾掉事件QEvent::FocusIn
的焦點,它實際上導致QEvent::RequestSoftwareInputPanel
。對於我們的應用程序,它應該是這樣工作的。 Android 鍵盤不再出現,我們的編輯文本字段仍然獲得焦點,因為我們有自己的焦點和鍵盤實現。 我相信這對每個人來說都不是完美的解決方案,這就是我稱之為解決方法的原因。 如果有人知道如何過濾輸出事件,特別是QEvent::RequestSoftwareInputPanel
,請在此處發布。 filter的最終實現是:
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);
}
}
};
QApplication::setAutoSipEnabled(false) 禁用軟件虛擬鍵盤自動彈出。 您可以使用“Q_OS_ANDROID”預處理器指令來避免修改其他目標平台上的行為:
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);
}
這是使用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();
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.