2

I've created a Virtual Keyboard control on a QML screen. However, while I can show and hide the keyboard in my code fine, when I press the "Dismiss" button, it doesn't hide.

I don't think this is a duplicate of QML Virtual keyboard Hide button not working because that question seems to be about the visibility not being bound to the active status whereas in my case, the active status is not being updated at all from what I can tell, and my setup is different. Also I'm not getting any error message while that poster did.

Here is my Keyboard input panel (Keyboard.qml):

import QtQuick 2.0
import QtQuick.VirtualKeyboard 2.1

InputPanel {
 id: keyboard

 z: 99
 y: parent.height
 anchors.left: parent.left
 anchors.right: parent.right

 onActiveChanged: {
     console.info("keyboard active changed"); // this doesn't get hit when I press the hide button
 }


 states: State {
     name: "visible"

     when: keyboard.active
     PropertyChanges {
         target: keyboard
         y: parent.height - keyboard.height
     }
 }
 transitions: Transition {
     from: ""
     to: "visible"
     reversible: true
     ParallelAnimation {
         NumberAnimation {
             properties: "y"
             duration: 250
             easing.type: Easing.InOutQuad
         }
     }
 }
 Binding {
     target: InputContext
     property: "animating"
     value: inputPanelTransition.running
 }     
}

Then on my QML screen I have this:

TextInput {
    id: myField
    anchors.fill: parent
    anchors.margins: vitalStyle.marginSmall

    horizontalAlignment: TextInput.AlignLeft
    verticalAlignment: TextInput.AlignBottom

    clip: true
    onTextChanged: {
         if (model.fieldType === SettingsManager.WLAN_PASSKEY) {
               resultData = text;
               dataUpdated++;
         }
    }

    MouseArea {
          anchors.fill: parent
          propagateComposedEvents: true
          onPressed:{
              keyboard.active = true;   // works fine - makes keyboard pop up.
              mouse.accepted = false;
          if( (otherScreen.visible) ) {
              keyboard.active = false; // works fine - hides keyboard if otherScreen is visible.
          }
    }

    onActiveFocusChanged: {
         console.info("active focus changed (basic)"); // doesn't get hit if I press the dismiss button.
         if( (focus) ) {
             cursorPosition = text.length;
             clearInputMethod();  
             console.info("activating keyboard");   // doesn't get hit if I press the dismiss button.
             keyboard.active = true;
         }
         else{
             clearInputFocus.enable();
         }

         EnterKeyAction.enabled: false
   }
}
.
.
.
.

function clearInputMethod() {

    // sets 'visible' to false of a number of other controls.     

    keyboard.active = false;
}

TextInput {
    id: clearInputFocus
    readOnly: true

    function enable() {
        forceActiveFocus();
        clearInputMethod();
    }
}

Keyboard {
   id: keyboard
}

I was afraid that pressing the 'Hide' button might cause the focus to go back to the text field and then maybe it was just popping it back up immeadiately because of the code in onActiveFocusChanged however those console.log statements aren't displaying anything when I press the Hide button so I don't think that's the case. Neither is the onActiveChanged event on the InputPanel itself being hit when I press the button. Though both are being hit when I first show the keyboard by clicking on the field.

The button itself does dim slightly as I press it, as all of the buttons do, so the button press is "occurring" if you get me.

komodosp
  • 3,316
  • 2
  • 30
  • 59

1 Answers1

0

I ended up having to use an "eventFilter" which detects when the region that the Hide button occupies is pressed. Not very elegant I know...

bool contentLoader::eventFilter( QObject *object, QEvent *event )
{
    if( (m_keyboardActive) &&
        (event->type() == QEvent::TouchEnd) )
    {
        QTouchEvent *touch = static_cast<QTouchEvent *>(event);
        if( (touch->touchPoints().count()) )
        {
            QTouchEvent::TouchPoint lastPoint = touch->touchPoints().last();

            //Normalised location of the Hide Keyboard Button
            QRectF hideButton_normalised( 0.8725, 0.90, 1.0, 1.0 ); //fullsize keyboard
            if( ((m_inputHint & Qt::ImhDigitsOnly) == Qt::ImhDigitsOnly) )
            {
                hideButton_normalised.setCoords( 0.55, 0.85, 0.87, 0.90 ); //numpad
            }

            if( (hideButton_normalised.contains( lastPoint.normalizedPos() )) )
            {
                hideKeyboard();
            }
        }
    }

and in the QML...

    Connections {
        target: contentHandler

        onHideKeyboard: {
            keyboard.active = false;
        }
    }
komodosp
  • 3,316
  • 2
  • 30
  • 59