how to deal with InputPanel (keyboard) covering input fields?
-
Hi all -
I've got an Input Panel that sits on the lower half of my screen (this is an embedded application with a dedicated display). If I have a screen full of TextFields, some of them get covered up when the keyboard appears.
I've tried putting my stuff inside a Flickable, but trying to flick dismisses the keyboard. I could probably find a way to fix this, but I'm wondering whether there's a better way to accomplish this in general.
Is there a way to force-position my Flickable to show the TextField being entered?
Thanks...
-
I have struggled with this on Android. To fix (hack) this I created a file VirtualKeyboarPageResizer.qml like this
import QtQuick Connections { property int fullPageHeight: 0 target: Qt.inputMethod // Resize the page when the Android virtual keyboard is shown function onKeyboardRectangleChanged() { if (Qt.inputMethod.keyboardRectangle.y > 0) { // Sometimes the page height gets changed automatically but most times not... // Setting to to keyboard-y seems reliable. const keyboardY = Qt.inputMethod.keyboardRectangle.y / Screen.devicePixelRatio parent.height = keyboardY } else { console.debug("HIDE KEYBOARD, PARENT:", parent.height, "CONTENT:", contentHeight) if (fullPageHeight > 0) parent.height = fullPageHeight else console.warn("fullPageHeight not set!") } } Component.onDestruction: { if (fullPageHeight > 0) parent.height = fullPageHeight } }
In a page with a TextEdit I have this:
Page { // page with TextEdit and other stuff VirtualKeyboardPageResizer { id: virtualKeyboardPageResizer } Component.onCompleted: { // Save the full page height now. Later when the Android keyboard pops up, // the page height sometimes changes by itself, but not always... virtualKeyboardPageResizer.fullPageHeight = parent.height } }
I am not happy with this, but it seems to work. The horrible part is that sometimes when the virtual keyboard pops up, the page height changes all by itself, hence the code in the onCompleted method. The text editing capabilities from QML are rather buggy on Android.
-
@Michel-de-Boer that's a creative solution. In my app, I don't want to resize anything - I just want to move the visible area of the flickable so the current field will show. And, I'm hoping there's some semi-automatic way of doing this, so I don't have to calculate Y values for each TextField on the screen.
-
If you find a decent way to solve this problem, I would love to know. Also I am curious if you get these weird issues that I have been seeing where the height of my page sometimes get changed by something in Qt itself.
-
@mzimmers Create a pop-up with a text field above virtual keyboard which looks like the one in the layout and type text into it. When typing is finished, copy the text content in the pop-up into the right text field and close(destroy) the pop-up.
-
@JoeCFD said in how to deal with InputPanel (keyboard) covering input fields? :
@mzimmers Create a pop-up with a text field above virtual keyboard which looks like the one in the layout and type text into it. When typing is finished, copy the text content in the pop-up into the right text field and close(destroy) the pop-up.
Thanks for providing solution.
-
This is what I ended up doing:
Flickable { Connections { target: passwordField function onTextFieldClicked(yValue, itemHeight) { contentY = (yValue + (itemHeight / 2)) - (height / 2) } } TextField { signal textFieldClicked(int yValue, int itemHeight) onActiveFocusChanged: { if (activeFocus) { textFieldClicked(y, height) }
It seems to work, though I'm not sure my calculation for contentY is 100% accurate. Maybe someone with a little idle time can improve on it.
-
-
QScrollArea has a method ensureWidgetVisible() which seems to be missing from Flickable. StackOverflow had a discussion on this: https://stackoverflow.com/questions/45946637/how-to-make-flickable-ensure-the-visibility-of-an-item-inside-of-it. (I'm not a user of QML, but this might provide a different way of tackling the problem.)