×
Namespaces

Variants
Actions
(Difference between revisions)

Workaround to hide VKB in QML apps (Known Issue)

From Nokia Developer Wiki
Jump to: navigation, search
gnuton (Talk | contribs)
(Gnuton - - Introduction)
hamishwillee (Talk | contribs)
m (Text replace - "<code cpp>" to "<code cpp-qt>")
 
(17 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:Draft]]
+
[[Category:Qt Mobility]][[Category:UI]][[Category:Qt]][[Category:MeeGo Harmattan]][[Category:Code Snippet]][[Category:Known Issue]]
{{Abstract|This article explains how to close the virtual keyboard in pure QML apps }}  
+
{{Abstract|This article explains how to close the virtual keyboard in pure QML apps.}}  
 
+
{{ArticleMetaData <!-- v1.2 -->
{{ArticleMetaData
+
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
Line 9: Line 8:
 
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|capabilities=<!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
+
|signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 +
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
|id= <!-- Article Id (Knowledge base articles only) -->
+
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
|language=<!-- Language category code for non-English topics - e.g. Lang-Chinese -->
+
|translated-by= <!-- [[User:XXXX]] -->
|review-by=<!-- After re-review: [[User:username]] -->
+
|translated-from-title= <!-- Title only -->
|review-timestamp=<!-- After re-review: YYYYMMDD -->
+
|translated-from-id= <!-- Id of translated revision -->
|update-by=<!-- After significant update: [[User:username]]-->
+
|review-by= <!-- After re-review: [[User:username]] -->
|update-timestamp=<!-- After significant update: YYYYMMDD -->
+
|review-timestamp= <!-- After re-review: YYYYMMDD -->
|creationdate= <!-- Format YYYYMMDD -->
+
|update-by= <!-- After significant update: [[User:username]]-->
|author= <!-- Display as link [[User:username]] -->
+
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 +
|creationdate= 20111028
 +
|author= [[User:gnuton]]
 
}}
 
}}
  
[[Category:Qt]][[Category:Qt Mobility]]
 
 
== Introduction ==
 
== Introduction ==
Pure QML application on Harmattan suffer of a bug which is quite annoying. The bug I'm talking about is related to the Virtual Keyboard (VKB). Basically when a QML element able to listen for key events receives the focus, a virtual keyboard shows up and user can enter the text in the element by tapping on the keyboard itself.
+
Pure QML applications on MeeGo Harmattan have an annoying bug in which the Virtual Keyboard (VKB) is not closed when you tap outside a selected text editing element.  
When user finished to insert text and tap outside the element, the previous element doesn't actually lose the focus and the keyboard is not closed automatically going against the logic way of usage and against the Harmattan guide lines.
+
This is not just annoying, but mess up the vocabulary other than the usability.
+
  
In this page we will talk about how to work around this, and which solutions are available.
+
What happens is that when a QML element that is able to listen for key events receives the focus, a virtual keyboard is displayed that the user can use for entering text. When the user taps outside the element to indicate they have finished entering text the element doesn't actually lose the focus, so the keyboard is not closed. This goes against the Harmattan style guidelines (and common sense).
  
UPDATE: This bug has been fixed and it will be released in Harmattan > PR 1.1
+
This article describes a number of workarounds to the problem.
 +
 
 +
{{Note|This bug has was reported as fixed in Harmattan > PR 1.1. Note however that more recently it has been reported as still valid on N9 handset, version PR1.2 (30.2012.07-1.348.2_PR_348) - compiling with Qt Creator 2.4.1, based on Qt 4.7.4, part of Nokia SDK as released in April 2012. The workaround is effective on that version.}}
  
 
== Pure QML Solution ==
 
== Pure QML Solution ==
Many and many times you could have heard that to get around this problem you should use [http://doc.qt.nokia.com/4.7-snapshot/qml-textinput.html#closeSoftwareInputPanel-method closeSoftwareInputPanel] QML method. Well, here is an example which shows you how to use it.
+
One workaround is to use [http://doc.qt.nokia.com/4.7-snapshot/qml-textinput.html#closeSoftwareInputPanel-method closeSoftwareInputPanel] QML method. The example below is the implementation of this fix inside a simple QML app made up of a root {{Icode|Rectangle}} element and a {{Icode|TextEdit}}. The virtual keyboard is shown when the {{Icode|TextEdit}} is clicked, but the virtual keyboard is not hidden when the user taps outside.
The example below is the implementation of this fix inside a simple QML app made up by a root Rectangle element and a textedit. The virtual keyboard is shown when the textedit is clicked, but the virtual keyboard is not hidden when the user taps outside.
+
The main problem here is related to the focus. Tapping outside the textedit element is not enough to change the focus and close the VKB, so we have to add some code to fulfill these duties.
+
The fix is implemented basically in two parts.
+
* MouseArea - a big and transparent to events Mousarea overlays the entire application. This allows us to give the focus to the clicked item
+
* onActiveFocusChanged slot inside the any element able to receive text input. This slot actually close the VKB
+
The rest of example is pretty simple and the complete code can be seen in the block of code below.
+
  
 +
The main problem here is related to the focus. Tapping outside the {{Icode|TextEdit}} element is not enough to change the focus and close the VKB, so we have to add some additional code. The fix is implemented basically in two parts:
 +
* {{Icode|MouseArea}} - a big and transparent to events {{Icode|MousArea}} overlays the entire application. This allows us to give the focus to the clicked item
 +
* {{Icode|onActiveFocusChanged}} slot inside the any element able to receive text input. This slot actually closes the VKB
 +
The rest of example is pretty simple and the complete code can be seen below:
 
<code javascript>
 
<code javascript>
 
 
import QtQuick 1.0
 
import QtQuick 1.0
 
     Rectangle {
 
     Rectangle {
Line 75: Line 73:
 
</code>
 
</code>
  
== C++ workaround==
+
== C++ workaround [BETTER SOLUTION]==
A pure C++ workaround consists of adding an event filter to the affected view instance  
+
A pure C++ workaround consists of adding an event filter to the affected view instance:
<code cpp>
+
<code cpp-qt>
 
class EventFilter : public QObject  
 
class EventFilter : public QObject  
 
{     
 
{     
Line 100: Line 98:
 
};  
 
};  
 
  </code>
 
  </code>
This filter can be installed on a QGraphicsView or (in QML) on a  
+
 
<code>
+
This filter can be installed on a {{Qapiname|QGraphicsView}} or (in QML) on a {{Qapiname|QDeclarativeView}} instance:
QDeclarativeView instance:
+
<code cpp-qt>
+
 
EventFilter ef;  
 
EventFilter ef;  
view.installEventFilter(&ef);  
+
view.installEventFilter(&ef);
 
+
 
</code>
 
</code>
  
 
== MeeGo Components are not affected! ==
 
== MeeGo Components are not affected! ==
While this bug affects plain QML apps, MeeGo component based apps are not affected by this bug at all! So if possibl you should use the Meego elements set instead of the standard QML ones.
+
While this bug affects plain QML apps, MeeGo component based apps are not affected! So if possible you should use the Meego elements set instead of the standard QML ones.
The only one drawback here is the compatibility with Symbian set. In fact, if your target is to run the app both on Symbian and MeeGo polatforms then the solution shown before is the right way to go.
+
The only one drawback here is the compatibility with Symbian set. In fact, if your target is to run the app both on Symbian and MeeGo polatforms then the second solution shown above is the right way to go.

Latest revision as of 04:19, 11 October 2012

This article explains how to close the virtual keyboard in pure QML apps.

Article Metadata
Article
Created: gnuton (28 Oct 2011)
Last edited: hamishwillee (11 Oct 2012)

Contents

[edit] Introduction

Pure QML applications on MeeGo Harmattan have an annoying bug in which the Virtual Keyboard (VKB) is not closed when you tap outside a selected text editing element.

What happens is that when a QML element that is able to listen for key events receives the focus, a virtual keyboard is displayed that the user can use for entering text. When the user taps outside the element to indicate they have finished entering text the element doesn't actually lose the focus, so the keyboard is not closed. This goes against the Harmattan style guidelines (and common sense).

This article describes a number of workarounds to the problem.

Note.pngNote: This bug has was reported as fixed in Harmattan > PR 1.1. Note however that more recently it has been reported as still valid on N9 handset, version PR1.2 (30.2012.07-1.348.2_PR_348) - compiling with Qt Creator 2.4.1, based on Qt 4.7.4, part of Nokia SDK as released in April 2012. The workaround is effective on that version.

[edit] Pure QML Solution

One workaround is to use closeSoftwareInputPanel QML method. The example below is the implementation of this fix inside a simple QML app made up of a root Rectangle element and a TextEdit. The virtual keyboard is shown when the TextEdit is clicked, but the virtual keyboard is not hidden when the user taps outside.

The main problem here is related to the focus. Tapping outside the TextEdit element is not enough to change the focus and close the VKB, so we have to add some additional code. The fix is implemented basically in two parts:

  • MouseArea - a big and transparent to events MousArea overlays the entire application. This allows us to give the focus to the clicked item
  • onActiveFocusChanged slot inside the any element able to receive text input. This slot actually closes the VKB

The rest of example is pretty simple and the complete code can be seen below:

import QtQuick 1.0
Rectangle {
id: root
width: 800
height: 600
focus: true
Rectangle {
width: 360
height: 360
color: "cyan"
TextEdit {
id: mText
anchors.fill: parent
onActiveFocusChanged: {
if (!mText.activeFocus) mText.closeSoftwareInputPanel();
}
}
}
MouseArea {
anchors.fill: parent
onPressed: {
// Let the mousePress events go to below items
mouse.accepted = false;
// Clicked item below the MouseArea gets the focus
var selectedItem = root.childAt(mouse.x, mouse.y);
if (!selectedItem) selectedItem = root;
selectedItem.focus = true;
}
}
}

[edit] C++ workaround [BETTER SOLUTION]

A pure C++ workaround consists of adding an event filter to the affected view instance:

class EventFilter : public QObject 
{
protected:
bool eventFilter(QObject *obj, QEvent *event) {
QInputContext *ic = qApp->inputContext();
if (ic) {
if (ic->focusWidget() == 0 && prevFocusWidget) {
QEvent closeSIPEvent(QEvent::CloseSoftwareInputPanel);
ic->filterEvent(&closeSIPEvent);
} else if (prevFocusWidget == 0 && ic->focusWidget()) {
QEvent openSIPEvent(QEvent::RequestSoftwareInputPanel);
ic->filterEvent(&openSIPEvent);
}
prevFocusWidget = ic->focusWidget();
}
return QObject::eventFilter(obj,event);
}
 
private:
QWidget *prevFocusWidget;
};

This filter can be installed on a QGraphicsView or (in QML) on a QDeclarativeView instance:

EventFilter ef; 
view.installEventFilter(&ef);

[edit] MeeGo Components are not affected!

While this bug affects plain QML apps, MeeGo component based apps are not affected! So if possible you should use the Meego elements set instead of the standard QML ones. The only one drawback here is the compatibility with Symbian set. In fact, if your target is to run the app both on Symbian and MeeGo polatforms then the second solution shown above is the right way to go.

This page was last modified on 11 October 2012, at 04:19.
100 page views in the last 30 days.
×