IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Viadeo Twitter Facebook Share on Google+   
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Toutes les fonctions  ·  Vues d'ensemble  · 

Le focus clavier en QML

Lorsqu'une touche est appuy�e ou rel�ch�e, un �v�nement clavier est g�n�r� et transmis � l'�l�ment Item QML ayant le focus. Pour faciliter la construction de composants r�utilisables et pour traiter certains cas propres aux interfaces utilisateur fluides, les �l�ments QML ajoutent une extension bas�e sur les port�es au mod�le de focus clavier traditionnel de Qt.

Aper�u de la gestion des touches

Lorsque l'utilisateur appuie sur une touche ou la rel�che, il se passe les choses suivantes :

  1. Qt re�oit l'action de la touche et g�n�re un �v�nement clavier ;
  2. si le widget Qt contenant la QDeclarativeView poss�de le focus, l'�v�nement clavier lui est transmis. Sinon, la gestion standard des touches de Qt se poursuit ;
  3. l'�v�nement clavier est transmis par la sc�ne � l'�l�ment Item QML poss�dant le focus. Si aucun �l�ment ne poss�de le focus, l'�v�nement clavier est ignor� et la gestion standard des touches de Qt se poursuit ;
  4. si l'�l�ment QML ayant le focus accepte l'�v�nement clavier, la propagation s'arr�te. Sinon, l'�v�nement est « remont� », il est pass� � chaque parent d'�l�ment jusqu'� ce que l'�v�nement soit accept� ou que l'�l�ment racine soit atteint. Si l'�l�ment Rectangle dans l'exemple suivant a le focus et que la touche A est appuy�e, l'�v�nement remontera � son parent. Sinon, l'appui sur la touche B remontera l'�v�nement vers l'�l�ment racine et il sera donc ignor�.
     Rectangle {
         width: 100; height: 100
         focus: true
         Keys.onPressed: {
             if (event.key == Qt.Key_A) {
                 console.log('Key A was pressed');
                 event.accepted = true;
             }
         }
     }
  5. si l'�l�ment Item racine est atteint, l'�v�nement clavier est ignor� et la gestion standard des touches de Qt se poursuit.

Voir aussi les propri�t�s-cl�s attach�es et propri�t�s KeyNavigation attach�es.

Conna�tre l'�l�ment poss�dant le focus

La propri�t� Item::activeFocus permet de savoir si un �l�ment poss�de le focus ou non. Voici un exemple o� le texte d'un �l�ment Text est d�termin� selon que l'�l�ment poss�de le focus ou non.

     Text {
         text: activeFocus ? "J'ai le focus !" : "Je n'ai pas le focus"
     }

Acqu�rir le focus et les port�es de focus

Un �l�ment Item demande le focus en d�finissant la propri�t� focustrue.

Pour les cas tr�s simples, la d�finition de la propri�t� focus est suffisante. En ex�cutant l'exemple suivant avec le QML Viewer, on voit que l'�l�ment keyHandler poss�de le focus et l'appui sur les touches A, B ou C modifie le texte selon la touche.

 Rectangle {
     color: "lightsteelblue"; width: 240; height: 25
     Text { id: myText }
     Item {
         id: keyHandler
         focus: true
         Keys.onPressed: {
             if (event.key == Qt.Key_A)
                 myText.text = 'Key A was pressed'
             else if (event.key == Qt.Key_B)
                 myText.text = 'Key B was pressed'
             else if (event.key == Qt.Key_C)
                 myText.text = 'Key C was pressed'
         }
     }
 }

image

Par contre, lorsque l'exemple ci-dessus doit �tre utilis� sous forme d'un composant import� ou r�utilis�, la simple utilisation de la propri�t� focus ne suffit plus.

Pour pr�senter ce cas, on cr�e deux instances du composant d�fini pr�c�demment et on donne le focus au premier. Le but est que, lorsque l'une des touches A, B ou C est appuy�e, le premier des deux composants re�oive l'�v�nement et r�ponde de fa�on appropri�e.

Le code qui importe et cr�e les deux instances de MyWidget est le suivant :

 // code de la fen�tre qui importe MyWidget
 Rectangle {
     id: window
     color: "white"; width: 240; height: 150
 
     Column {
         anchors.centerIn: parent; spacing: 15
 
         MyWidget {
             focus: true             // Donne le focus � ce MyWidget
             color: "lightblue"
         }
         MyWidget {
             color: "palegreen"
         }
     }
 }

Voici le code de MyWidget :

 // code de MyWidget
 Rectangle {
     id: widget
     color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true
     Text { id: label; anchors.centerIn: parent}
     focus: true
     Keys.onPressed: {
         if (event.key == Qt.Key_A)
             label.text = 'Key A was pressed'
         else if (event.key == Qt.Key_B)
             label.text = 'Key B was pressed'
         else if (event.key == Qt.Key_C)
             label.text = 'Key C was pressed'
     }
 }

On aimerait donner le focus au premier objet MyWidget en d�finissant la propri�t� focustrue. Cependant, en ex�cutant le code, on constate que c'est second widget qui re�oit le focus.

image

En observant le code de MyWidget et celui de la fen�tre window, le probl�me est �vident - il y a trois �l�ments qui d�finissent la propri�t� focustrue. Les deux MyWidget d�finissent le focustrue et le composant fen�tre window �galement. En d�finitive, un seul �l�ment peut poss�der le focus clavier et le syst�me doit d�cider quel �l�ment recevra l'�v�nement. Lorsque le second MyWidget est cr��, il re�oit le focus car c'est le dernier �l�ment � d�finir la propri�t� focustrue.

Ce probl�me est d� � la visibilit�. Le composant MyWidget aimerait avoir le focus mais il ne peut pas contr�ler le focus lorsqu'il est import� ou r�utilis�. Pareillement, le composant fen�tre window n'a pas la capacit� de savoir si ses composants import�s demandent le focus.

Pour r�soudre ce probl�me, le QML introduit un concept connu sous le nom de port�e de focus (focus scope). Pour les utilisateurs de Qt, une port�e de focus ressemble � un proxy automatique pour le focus. La port�e est cr��e en d�clarant l'�l�ment FocusScope.

Dans l'exemple suivant, un �l�ment FocusScope est ajout� au composant.

 FocusScope {
 
     // Le FocusScope doit se lier aux propri�t�s visuelles du Rectangle
     property alias color: rectangle.color
     x: rectangle.x; y: rectangle.y
     width: rectangle.width; height: rectangle.height
 
     Rectangle {
         id: rectangle
         anchors.centerIn: parent
         color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true
         Text { id: label; anchors.centerIn: parent }
         focus: true
         Keys.onPressed: {
             if (event.key == Qt.Key_A)
                 label.text = 'Key A was pressed'
             else if (event.key == Qt.Key_B)
                 label.text = 'Key B was pressed'
             else if (event.key == Qt.Key_C)
                 label.text = 'Key C was pressed'
         }
     }
 }

Voici le r�sultat visuel :

image

Conceptuellement, les port�es de focus sont tr�s simples.

  • Dans chaque port�e de focus, un seul �l�ment peut avoir la propri�t� Item::focus d�finie � true. Si plus d'un �l�ment Item activent la propri�t� focus, le dernier �l�ment � d�finir le focus poss�dera le focus et les autres le perdront, comme lorsque qu'il n'y avait pas de port�e.
  • Lorsqu'une port�e de focus re�oit le focus, l'�l�ment contenu ayant la propri�t� focus activ�e (s'il existe) re�oit aussi le focus. Si cet �l�ment est lui-m�me un FocusScope, ce comportement se r�p�te. La propri�t� activeFocus sera activ�e � la fois pour la port�e de focus et le sous-�l�ment poss�dant le focus.

Notez que, comme l'�l�ment FocusScope n'est pas un �l�ment visuel, les propri�t�s de ses enfants doivent �tre expos�es � l'�l�ment parent du FocusScope. Les dispositions et les �l�ments de positionnement utiliseront ces propri�t�s visuelles et de styles pour d�terminer le positionnement. Dans notre exemple, l'�l�ment Column ne peut afficher les deux widgets correctement car le FocusScope ne poss�de pas de propri�t�s visuelles. Le composant MyWidget se lie directement aux propri�t�s de rectangle pour permettre � l'�l�ment Column de cr�er la disposition contenant l'enfant du FocusScope.

Jusqu'ici, l'exemple activait statiquement le focus sur le second composant. Il est maintenant trivial d'�tendre ce composant pour le rendre cliquable, et de l'ajouter � l'application d'origine. On attribue toujours le focus initial � l'un des widgets. Maintenant, un clic sur l'un des MyClickableWidget lui donnera le focus et l'autre widget le perdra.

Voici le code qui importe et cr�e les deux instances de MyClickableWidget :

 Rectangle {
     id: window
 
     color: "white"; width: 240; height: 150
 
     Column {
         anchors.centerIn: parent; spacing: 15
 
         MyClickableWidget {
             focus: true             // donne le focus � ce MyWidget
             color: "lightblue"
         }
         MyClickableWidget {
             color: "palegreen"
         }
     }
 
 }

Voici le code de MyClickableWidget :

 FocusScope {
 
     id: scope
 
     // Le FocusScope doit se lier aux propri�t�s visuelles de l'enfant
     property alias color: rectangle.color
     x: rectangle.x; y: rectangle.y
     width: rectangle.width; height: rectangle.height
 
     Rectangle {
         id: rectangle
         anchors.centerIn: parent
         color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true
         Text { id: label; anchors.centerIn: parent }
         focus: true
         Keys.onPressed: {
             if (event.key == Qt.Key_A)
                 label.text = 'Key A was pressed'
             else if (event.key == Qt.Key_B)
                 label.text = 'Key B was pressed'
             else if (event.key == Qt.Key_C)
                 label.text = 'Key C was pressed'
         }
     }
     MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
 }

image

Lorsqu'un �l�ment abandonne explicitement le focus (en affectant la valeur false � sa propri�t� focus lorsqu'il poss�de le focus), le syst�me ne transmet pas automatiquement le focus � un autre �l�ment. � ce moment, il est possible qu'aucun �l�ment ne poss�de le focus.

Voir l'exemple de focus clavier pour une d�monstration d'un focus clavier passant entre diff�rentes zones en utilisant les �l�ments FocusScope.

Utilisation avanc�e des port�es de focus

Les port�es de focus permettent de facilement partitionner l'allocation du focus. Plusieurs �l�ments QML l'utilisent dans ce but.

Par exemple, ListView est elle-m�me une port�e de focus. G�n�ralement, cela ne se remarque pas car ListView ne poss�de habituellement pas d'enfants visuels ajout�s manuellement. �tant une port�e de focus, la ListView peut donner le focus � l'�l�ment courant de la liste sans se soucier des effets sur le reste de l'application. Cela permet au d�l�gu� de l'�l�ment courant de r�agir aux touches du clavier.

Cet exemple artificiel montre comment cela fonctionne. L'appui sur la touche Entr�e affichera le nom de l'�l�ment courant de la liste.

 Rectangle {
     color: "lightsteelblue"; width: 100; height: 50
 
     ListView {
         anchors.fill: parent
         focus: true
 
         model: ListModel {
             ListElement { name: "Bob" }
             ListElement { name: "John" }
             ListElement { name: "Michael" }
         }
 
         delegate: FocusScope {
                 width: childrenRect.width; height: childrenRect.height
                 x:childrenRect.x; y: childrenRect.y
                 TextInput {
                     focus: true
                     text: name
                     Keys.onReturnPressed: console.log(name)
                 }
         }
     }
 }

image

Bien que l'exemple soit simple, beaucoup de choses se d�roulent en coulisse. Chaque fois que l'�l�ment courant change, la ListView active la propri�t� Item::focus du d�l�gu�. Comme le ListView est une port�e de focus, cela n'affecte pas le reste de l'application. Par contre, si la ListView poss�de le focus, le d�l�gu� lui-m�me recevra le focus. Dans cet exemple, l'�l�ment racine du d�l�gu� est aussi une port�e de focus, qui donne le focus � l'�l�ment Text qui effectue le travail de gestion de la touche Entr�e.

Toutes les classes vues de QML, telles que PathView et GridView, se comportent de mani�re similaire et permettent la gestion des touches dans leurs d�l�gu�s respectifs.

Remerciements

Merci � Alexandre Laurent pour la traduction ainsi qu'� Ilya Diallo, Jonathan Courtois, Thibaut Cuvelier et Claude Leloup pour leur relecture !

Cette page est une traduction d'une page de la documentation de Qt, �crite par Nokia Corporation and/or its subsidiary(-ies). Les �ventuels probl�mes r�sultant d'une mauvaise traduction ne sont pas imputables � Nokia. Qt 4.7
Copyright © 2025 Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'� 3 ans de prison et jusqu'� 300 000 E de dommages et int�r�ts. Cette page est d�pos�e � la SACD.
Vous avez d�nich� une erreur ? Un bug ? Une redirection cass�e ? Ou tout autre probl�me, quel qu'il soit ? Ou bien vous d�sirez participer � ce projet de traduction ? N'h�sitez pas � nous contacter ou par MP !