Search code examples
c++qtqmlqtvirtualkeyboard

C++ [QT 5.15.2] : virtual keyboard shift button is disabled until I click on my textField


I'm developping an app using QT 5.15 LTS (5.15.2). I have the following QML item that I use to handle virtual keyboard interactions :

//InputScreen.qml
import QtQuick 2.3
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import QtQuick.VirtualKeyboard 2.3

Rectangle
{
    id: inputScreen
    property var target: undefined

    width: app.width
    height: app.height
    color: "#44000000"
    z: 200

    onVisibleChanged:
    {
        if (inputScreen.visible == true)
        {
            fld.text = target.text;
            inputPanel.forceActiveFocus();
            fld.forceActiveFocus();
            fld.clicked(); //Tried to force a click here. Explanation below
        }
    }

    Rectangle
    {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        height: 40
        width: 600
        z: 201

        TextField
        {
            id: fld
            anchors.left: parent.left
            anchors.verticalCenter: parent.verticalCenter
            width: 400
            height: 40
            font.pixelSize: 24
            focus: true
        }

        Button
        {
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            width: 200
            height: 40
            font.pixelSize: 24
            text: "Valider"

            onClicked:
            {
                if (target != undefined)
                {
                    target.text = fld.text;
                    inputScreen.visible = false;
                }
            }
        }
    }

    InputPanel
    {
        id: inputPanel
        height: 400
        width: app.width - 40
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        focus: true

        z: 201
    }

    MouseArea
    {
        anchors.fill: parent
        onClicked:
        {
            target.text = fld.text;
            inputScreen.visible = false;
        }
    }
}

When my item becomes visible, the textField gets the focus correctly and I can start typing through the InputPanel virtual keyboard. There's however one single problem : the shift key does not work !

In order to make that shift key enable itself, I need to click on the TextField, which beats the purpose of forcing the active focus on it to begin with.

Is there any way to fix that problem ? Or at the very least, is there any kind of workaround I can use to enable that shift key ?

I have already tried to force a click inside my TextField (as seen in the code above), but it didn't work.

For context : here's the content of main.qml as well, in order to give out a working example :

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4
import QtQuick.VirtualKeyboard 2.3

Window
{
    id: app
    visible: true
    width: 640
    height: 480
    title: qsTr("Example")

    InputScreen
    {
        id: inputScreen
        visible: false
    }

    Rectangle
    {
        id: rect
        height: parent.height * 0.8
        width: parent.width * 0.8
        anchors.centerIn: parent
        border.color: "#FF0000"
        z: 1

        TextField
        {
            id: myField
            anchors.centerIn: parent
            width: 200
            height: 24

            MouseArea
            {
                anchors.fill: parent
                onClicked:
                {
                    inputScreen.target = myField;
                    inputScreen.visible = true;
                }
            }
        }
    }
}

Solution

  • I finally managed to find a trick that enabled that shift key without requiring to click on my already focused TextField, and it's actually very simple.

    I simply added the following line in the onClicked event of the MouseArea inside the "myField" TextField :

    MouseArea
    {
        anchors.fill: parent
        onClicked:
        {
            parent.focus = true; //This line solved the issue !
            //...
        }
    }
    

    I have no idea why, but somehow this was enough to actually unlock the shift key from my InputPanel virtual keyboard without requiring me to click a second time on the TextField from my InputScreen item. I suppose it has probably something to do with the fact that my MouseArea is hijacking the focus of the "myField" TextField, which triggers some sort of odd behaviour on the InputPanel item despite having another TextField item focused.

    In any case, I hope this will help someone.