2017-05-21 2 views
1

J'ai un menu contenant plusieurs éléments, tous avec des raccourcis d'accélérateur définis en utilisant la méthode de caractère de tabulation. Comme ceci:Interception des touches de l'accélérateur à l'intérieur wxTextCtrl

Increase volume\tCtrl+Up 

Jusqu'ici tout va bien. Cependant, deux de mes accélérateurs utilisent respectivement les raccourcis Ctrl + Gauche et Ctrl + Droite. Mon problème est que tout en se concentrant sur un TextCtrl, ces raccourcis ont déjà une fonction attendue - dans les champs de texte, Ctrl + Gauche et Ctrl + Droite devraient naviguer par mot. La majorité de mes utilisateurs vont utiliser le clavier très fortement, il est donc essentiel que ces fonctions fonctionnent comme prévu. Jusqu'ici, j'ai travaillé sur le fait que je peux intercepter toutes les clés avant qu'elles ne soient traitées pour l'utilisation de l'accélérateur en liant un gestionnaire pour wxEVT_CHAR_HOOK. Mais je ne suis pas tout à fait sûr de la façon de le faire. Je veux définir un ensemble de raccourcis qui doivent être transmis à TextCtrl, mais permettre aux autres accélérateurs d'être traités normalement s'ils n'ont pas de fonction spécifique à TextCtrl. Par exemple, Ctrl + Gauche et Ctrl + Droite devraient être traités par TextCtrl car ils naviguent par mot, mais Ctrl + O devrait déclencher sa commande de menu associée parce que TextCtrl n'a aucune utilité pour ce raccourci particulier.

La modification des raccourcis (par exemple Alt + Gauche au lieu de Ctrl + Gauche) n'est pas une option ici car l'application permet aux utilisateurs de modifier de façon interactive les accélérateurs. Désactiver les éléments de menu problématiques quand un TextCtrl a le focus ne fonctionnera pas non plus, parce que les raccourcis d'accélérateur associés n'exécutent toujours pas leurs fonctions prévues dans le TextCtrl (ie désactivant l'élément de menu avec l'accélérateur Ctrl + Left ne fait pas magiquement le TextCtrl traite correctement cette combinaison de touches). Ce dernier point semble être un bug dans wx, mais c'est comme ça.

+0

@ JamesSholes, donc si l'utilisateur décide de définir "Ctrl + X" à quelque chose - comment allez-vous gérer une telle situation? Je pense que vous devriez définir votre accélérateur à quelque chose de différent si le texte ctrl a le focus. Ou dériver du contrôle de texte et redéfinir le gestionnaire de clavier pour cela. – Igor

+0

Sous Windows, si l'utilisateur choisit d'utiliser Ctrl + X comme accélérateur, cela ne fonctionnera pas car le contrôle de texte interceptera le message WM_CUT. Je ne sais pas quel serait le comportement sur d'autres plateformes. Dans tous les cas, même si je sous-classe TextCtrl, cela ne fera probablement pas de différence car la fonctionnalité KeyDown n'est tout simplement pas atteinte. L'ordre de résolution pour la manipulation de la clé va wxEVT_HOOK -> tables d'accélérateur -> wxEVT_KEY_DOWN. Votre suggestion de modifier le texte de l'accélérateur quand un TextCtrl a un focus est intéressante, cependant; Je vais y réfléchir. Merci d'avoir commenté! –

Répondre

1

Si vous rencontrez ce problème sous Windows, en remplaçant wxWindow::MSWShouldPreProcessMessage() et en renvoyant false pour les combinaisons de touches en question, vous devez le corriger. Ceci est, cependant, une solution uniquement C++, je ne sais pas si même wxPhoenix fournit un moyen de remplacer les méthodes virtuelles de Python (et presque certain que wxPython classique ne le fait pas). Il est probable que la version de la bibliothèque dans wxTextCtrl::MSWShouldPreProcessMessage() devrait déjà faire cela, donc peut-être que vous pourriez modifier wxWidgets lui-même (et soumettre un patch avec vos modifications pour ne pas avoir à les maintenir vous-même).

+0

Vraiment utile, merci. Je suis une personne wxPython et je n'ai pas essayé le C++, mais je vais certainement envisager de soumettre un patch. Le code que vous pointez ne semble pas trop complexe. Une préoccupation est que les accélérateurs à une seule lettre tomberaient quand même dans les failles, même après avoir modifié 'wxTextCtrl :: MSWShouldPreProcessMessage'. –