簡體   English   中英

在 qml 應用程序中禁用 Android 鍵盤

[英]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 文件。 QtApplicationQtActivity派生自ApplicationActivity Android 類。

是否可以在應用程序啟動時全局禁用整個應用程序的 Android 鍵盤(編輯清單文件或覆蓋onCreateonStart或類似功能)? ApplicationActivity類中是否有任何函數可以覆蓋它們並因此禁用本機鍵盤?

一段時間后,我找到了解決方案,實際上是解決此問題的方法。 這個想法是使用一個請求軟件輸入面板( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM