Bonjour,
je cherchais un moyen de créer des raccourcis globaux pour un logiciel.
Pour rappel ces raccourcis sont actifs même lorsque la fenêtre du logiciel n'est, elle, plus active.
Alors ma façon de faire est une sorte de détournement, en utilisant un keylogger nommé xinput (linux) mais utilisable avec un autre keylogger normalement...
En plus de cela il faut un dictionnaire contenant la liste des touches et de leur numéro, xmodmap pour linux par exemple.
Cette fonction active ou désactive l'utilisation des raccourcis globaux, crée la liste des touches et lance le keylogger:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 def GlobalShortCut(self, Value): """Fonction permettant l'utilisation de raccourcis globaux.""" if Value: self.Touches = [] # Variable contenant les combinaisons de touche ### Création d'un QProcess qui exécutera xinput pour récupérer les touches self.ProcessKey = QProcess() # Création du QProcess self.ProcessKey.setProcessChannelMode(1) # Unification des 2 sorties (normale + erreur) du QProcess self.ProcessKey.readyReadStandardOutput.connect(self.XInput) # Connexions des retours de xinput à la fonction self.XInput ### Création du dictionnaire des touches self.KeyMap = {} # Dictionnaire contenant la liste des touches self.CmdInProgress = "Xmodmap" # Nom de la commande lancée self.ProcessKey.start("xmodmap -pke") # Commande à exécuter self.ProcessKey.waitForFinished() # Attend la fin de la commande ### Lancement du keylogger self.CmdInProgress = "Xinput" # Nom de la commande lancée self.ProcessKey.start("xinput test 9") # Commande à exécuter else: try: self.processKey.terminate() # Arrete le process if not self.processKey.waitForFinished(500): # Attend 1/2 seconde self.processKey.kill() # kill le process except: pass # Dans le cas ou le process n'existe pas
Cette fonction travaille sur les retours des commandes Xinput et Xmodmap :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 def XInput(self): """Fonction recevant tous les retours des touches utilisées.""" ### Récupération du retour (les 2 sorties sont sur la standard) data = self.ProcessKey.readAllStandardOutput() ### Converti les data en textes et les traite for Line in bytes(data).decode('utf-8').splitlines(): if self.CmdInProgress == "Xmodmap": KeyInfo = Line.replace(" ", " ").replace(" ", " ").split(" ") # Vire les espaces en trop et crée une liste if len(KeyInfo) > 3: # Ne conserve que les liste ayant plus de 3 éléments self.KeyMap[KeyInfo[1]] = KeyInfo[3] # Remplit le dictionnaire des touches elif self.CmdInProgress == "Xinput": ### Si une touche est relâchée et que self.Touches contient une combinaison de touche if "key release" in Line and self.Touches: ### Lance l'action adaptée if self.Touches == ["Control_L", "F2"]: self.Action("Start") elif self.Touches == ["Control_L", "F3"]: self.Action("Pause") elif self.Touches == ["Control_L", "F4"]: self.Action("Stop") elif self.Touches == ["Control_L", "F5"]: self.Action("Play") self.Touches = [] # Réinitialisation de la combinaison de touche ### Si une touche est pressée elif "key press" in Line: # Récupère le numéro de la touche keycode = Line.strip().split(" ")[-1] # Ajoute la touche si c'est le control gauche ou que Control gauche est déjà utilisé if self.keymap[keycode] == "Control_L" or self.Touches: self.Touches.append(self.keymap[keycode])
Alors voilà ma façon de faire...
Alors oui, c'est un keylogger mais j'essaie vraiment de faire en sorte de ne conserver que les combinaisons dont j'ai besoin.
Si vous avez d'autres façons de faire ou des idées pour améliorer le systeme, je prends
En espérant que cela puisse servir à d'autres personnes...
Partager