Disable Android keyboard in qml application

久未见 提交于 2021-01-27 13:01:56

问题


I'm porting an existing QML/C++ application to the Android system. The application is already running on the Android tablet, but I have issues with Android keyboard. Since my QML/C++ application has implemented its own keyboard, I would like to disable an Android one. I've tried to add android:windowSoftInputMode="stateAlwaysHidden" line in AndroidManifest.xml file, but keyboard still appears when I press an edit box. Since I'm porting an existing application, I do not want to edit the code of application itself. The only things I can edit are AndroidManifest.xml, QtApplication.java and QtActivity.java files. QtApplication and QtActivity are derived from Application and Activity Android classes.

Is it possible to disable the Android keyboard globally for whole app at the startup of application(with editing manifest file or overriding onCreate, onStart or similar functions)? Are there any functions in Application and Activity classes that I can override them and consequently disable native keyboard?


回答1:


After some time I found a solution, actually workaround for this problem. The idea was to consume an event that requests Software Input Panel (QEvent::RequestSoftwareInputPanel). This event is sent by QML/C++ application to the host Android system. So, I implemented an event filter called 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);
            }
        }
    };

This filter has to be installed to QCoreApplication berfore the QCoreApplication::run is called.

QCoreApplication *coreApp = QCoreApplication::instance();
SIPRequestEater *sipRequestEater = new SIPRequestEater();
coreApp->installEventFilter(sipRequestEater);

It can be installed also on QApllication.

The problem is, that this filter does not catch QEvent::RequestSoftwareInputPanel event. My explanation for this is that filters, which are installed with QCoreApplication::installEventFilter(<filter>) are filters only for input events, from Android to QML application. QEvent::RequestSoftwareInputPanel is actually going in other direction, from QML application to the Android system. I didn't find out if it is possible to filter/disable output events. Because of this I decided to filter out the focus in event QEvent::FocusIn which actually causes QEvent::RequestSoftwareInputPanel.For our application this works as it should. The Android keyboard is not appearing anymore and our edit text fields still get focus, because we have our own implementation of focus and keyboard. I believe that this is not the perfect solution for everyone, that's why I called it workaround. If someone knows, how to filter out output events, specially QEvent::RequestSoftwareInputPanel, please post it here. The final implementation of filter is:

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);
        }
    }
};



回答2:


QApplication::setAutoSipEnabled(false) disables the software virtual keyboard from popping up automatically. You can use the "Q_OS_ANDROID" preprocessor directive to avoid modifying behavior on your other target platforms:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

#ifdef Q_OS_ANDROID
    a.setAutoSipEnabled(false);
#endif
    (...)
}

You can programmatically display or hide the virtual keyboard using this code:

QInputMethod* input;
input = QGuiApplication::inputMethod();

if(input->isVisible())
{
    input->setVisible(false);
}
else
{
    input->setVisible(true);
}


来源:https://stackoverflow.com/questions/31275870/disable-android-keyboard-in-qml-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!