TextField and keyboard on Android
-
I have simple QML app, that shows only one TextField:
Rectangle { color: "#00000000" TextField { anchors.centerIn: parent } }
I thought, that Android keyboard will be shown automatically, when I touch on TextField, but it's not happening.
I tried to change focus, Qt.inputMethod.show() and many other methods, but keyboard not shown anyway.
Is that a bug? -
@clochydd How can I use this function? It must be placed into Component.onCompleted?
Update:
import QtQuick 2.5 import QtQuick.Controls 1.4 Rectangle { color: "#00000000" TextField { anchors.centerIn: parent Component.onCompleted: { focus = true; forceActiveFocus(); } } }
Tried like this, but no effect. ):
-
Any ideas? Why so simple and important function don't work?
#include <QtQuick> #ifdef QT_WEBVIEW_WEBENGINE_BACKEND #include <QtWebEngine> #endif #include "CameraAndroid.h" #include "JNINative.h" int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); #ifdef Q_OS_OSX // On OS X, correct WebView / QtQuick compositing and stacking requires running // Qt in layer-backed mode, which again resuires rendering on the Gui thread. qWarning("Setting QT_MAC_WANTS_LAYER=1 and QSG_RENDER_LOOP=basic"); qputenv("QT_MAC_WANTS_LAYER", "1"); qputenv("QSG_RENDER_LOOP", "basic"); #endif #ifdef QT_WEBVIEW_WEBENGINE_BACKEND QtWebEngine::initialize(); #endif // QT_WEBVIEW_WEBENGINE_BACKEND QQuickView view; view.setSource(QUrl("qrc:/main.qml")); view.setFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::WindowTitleHint); view.setFlags(view.flags() | static_cast<Qt::WindowFlags>(Qt::WA_TranslucentBackground)); view.setResizeMode(QQuickView::SizeRootObjectToView); view.setColor(QColor(Qt::transparent)); view.showFullScreen(); QObject::connect(view.rootContext()->engine(), SIGNAL(quit()), QGuiApplication::instance(), SLOT(quit())); return a.exec(); }
I post here code from main program. May be this can help to handle problem.
Update
Also tried to use TextInput, but no keyboard... -
@Skroopa Initially you should put it in your Rectangle:
Rectangle { color: "#00000000" TextField { id: myText anchors.centerIn: parent //.... } Component.onCompleted: { myText.forceActiveFocus(); } }
And if the activefocus is changed later in your program you should restore it:
myText.forceActiveFocus()
Hope, it helps
-
The following works for me on Android 4.3. Does it work for you?
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
main.qml
import QtQuick 2.6 import QtQuick.Controls 1.5 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { color: "#00000000" anchors.fill: contentItem TextField { anchors.centerIn: parent } } Button { anchors.bottom: contentItem.bottom text: "Exit" onClicked: Qt.quit() } }
-
@Wieland God bless you, sir! It works,
but only if you are using ApplicationWindow... It's a bug?
I think, we found the right path!Update:
The main feature of my application, that QML GUI draws over Android's SurfaceView. Qt don't provide any tools to use Android's MediaCodec-s and I must to use Qt::WA_TranslucentBackground and Qt::WindowStaysOnTopHint flags to achive "layer-cake" like app.
But if I use this flags, TextField / TextInput doesn't show keyboard anymore ))))):
Is it possible to show keyboard or I must write my own keyboard widget? -
Simple example:
#include <QtQuick> int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); QQuickView view; view.setSource(QUrl("qrc:/main.qml")); view.setFlags(Qt::WindowStaysOnTopHint | static_cast<Qt::WindowFlags>(Qt::WA_TranslucentBackground)); view.showFullScreen(); QObject::connect(view.rootContext()->engine(), SIGNAL(quit()), QGuiApplication::instance(), SLOT(quit())); return a.exec(); }
Setting any flags to QQuickView makes TextField unfocusable and keyboard never shows on Android (not tested on iOS). Is it possible way to solve trouble with keyboard?
I think, it is very important bug.UPDATE
Also, I tried this:view.setFlags(view.flags());
result the same - no keyboard. I'm sure - it's a bug.
Please, someone, help. Project is stuck. -
I don't think it's a bug. The
Qt::WindowStaysOnTopHint
flag forbids the keyboard "window" to come up. Maybe you can work around it by removing this flag everytime before the keyboard shall be shown. -
Okay, after week I found the next strange things of ApplicationWindow, when I set
flags: Qt.WindowStaysOnTopHint
to it:- ApplicationWindow now is inactive, i.e. ApplicationWindow.active == false.
requestActivate()
doesn't help -active
is false anyway. - ApplicationWindow's activeFocusItem == null.
There is two reasons, why keyboard doesn't show on Android after touching to TextField.
Any ideas, how to fix that? Thanks. - ApplicationWindow now is inactive, i.e. ApplicationWindow.active == false.
-
Tried this:
QGuiApplication a(argc, argv); QQmlApplicationEngine engine(QUrl(QStringLiteral("qrc:/main.qml"))); for(int i = 0; i < a.allWindows().size(); i++) { if(a.allWindows()[i]->objectName() == "mainWindow") { a.allWindows()[i]->requestActivate(); break; } }
Without results...
a.focusWindow()
is NULL. Can anyone help to me?
ApplicationWindow is fullscreen and has width and height equal Screen size.
Spent for this problem more than 2 weeks - no help in any forum...P.S. on Windows OS all works perfectly - window activates and focusWindow() is not NULL (gives me
ApplicationWindow_QMLTYPE_73(0x6335590, name="mainWindow")
) -
Done!
for(int i = 0; i < a.allWindows().size(); i++) { if(a.allWindows()[i]->objectName() == "mainWindow") { a.allWindows()[i]->close(); a.allWindows()[i]->setFlags(static_cast<Qt::WindowFlags>(a.allWindows()[i]->flags()) | Qt::WindowStaysOnTopHint); a.allWindows()[i]->show(); a.allWindows()[i]->showFullScreen(); break; } }
and keyboard is showing now! Hell, yeah!
Also, you must not set any flags to ApplicationWindow in QML code, otherwise keyboard will be hidden. -
@Wieland Ha-ha! (:
Someone today would be drunk... -
when the window inactive, just raise it
onActiveChanged:{
if(!rootWin.active){
rootWin.raise()
console.log("rootWin raise")
}
}