Python - Copier rapidement une suite de mots dans le Presse-papiers


Le Presse-papiers (Clipboard) est pratique mais il permet de mémoriser qu'une seule chose à la fois. Si on a besoin de recopier, dans un document cible, une suite de mots présents dans un document source, dans un ordre différent, il faut réaliser plusieurs fois les opérations Sélectionner, Copier, placer le Curseur et Coller les unes à la suite des autres. Cela prend du temps et devient vite fastidieux si on doit le répéter un grand nombre de fois.

Avec un choix possible de n mots différents, on peut construire un nombre total d'arrangements t= a(n,1)+a(n,2)+...+a(n,n), avec a(n,k)=n!/(n-k)!.
Avec 3 mots a, b et c : t= a(3,1) + a(3,2)+a(3,3)= 3 + 3x2 + 3x2 =15. On a les 15 arrangements suivants : a, b, c, ab, ac, ba, bc, ca, cb, abc, acb, bca, bac, cab et cba
Avec n mots t= n!/(n-1)! + n!/(n-2)! + ...+ n!/1! + n!/0! > 2n!
Le nombre de possibilités devient vite considérable...

Le programme suivant permet d'effectuer une copie rapide d'une suite de mots dans le presse-papiers, en choisissant ces mots dans un ordre quelconque dans une liste de n mots prédéfinis. Dans le cas présent les n mots prédéfinis sont des prénoms et des noms de famille, utilisés pour commenter un grand nombre de photos, mais on peut naturellement choisir d'autres mots avec une utilisation diiférente.

Ce programme est écrit ici en Python 3.6.9 sous Ubuntu 18.04; il passe par la réalisation des tâches suivantes :
1) Vérifier la présence du paquet xclip;
2) Vérifier la présence du paquet pyperlib;
3) Vérifier la présence du module Python tkinter;
4) Vérifier la présence d'un IDE Python (Thonny par exemple);
5) Créer le programme.

Programmation Python - Architecture matérielle et logicielle - IDE thonny, python, tkinter, pyperclip, xclip, X Window ou X11, Noyau Linux

1) Vérifier la présence du paquet xclip

Sous Linux, le système X Window (également appelé X11) est le logiciel de base qui gère l'écran, la souris et le clavier. xclip est une interface pour le système X11 qui permet d'utiliser le Presse-papiers en ligne de commande ou en programmation.

On vérifie si l'interface xclip est installée à l'aide de la commande dpkg-query -l

01

Si le paquet xclip n'apparaît pas dans la liste des paquets installés, on l'installe à l'aide des commandes suivantes :
sudo apt update
sudo apt install xclip

2) Vérifier la présence du paquet pyperlib

Pyperclip est un module Python qui permet d'utiliser le Presse-papiers depuis des programmes sources Python. Pyperclip s'appuie sur l'interface xclip pour pouvoir fonctionner. Si l'interface xclip n'est pas installée, pyperclip ne peut pas fonctionner.
On vérifie si le module pyperclip est installé à l'aide de la commande pip3 list

02

Si le module pyperclip n'apparaît pas dans la liste des modules installés, on l'installe à l'aide de la commande suivante :
python -m pip install -U pyperclip

En effet, une commande python -m pip install -U CePaquet installe la dernière version du paquet mentionné depuis le Python Package Index (PyPI - dépôt des paquets du lan- gage python). Si le paquet est déjà installé, il ne sera pas réinstallé.
Le paramètre -U, permet de modifier le paquet éventuellement existant sur l’ordinateur afin qu’il soit upgradé vers la version la plus récente.
La syntaxe python -m pip install –upgrade cePaquet est une variante de la syntaxe précédente.
La commande peut être utilisée sans le paramètre -U si on sait que le paquet souhaité n’existe pas déjà, dans une ancienne version, sur l’ordinateur.

On peut également installer pyperclip sans passer par pip, à l'aide des commandes suivantes :
sudo apt update
sudo apt install python3-pyperclip

On peut tester le fonctionnement de pyperclip à l'aide du programme test.py suivant (un simple ctrl-v permet ensuite de coller le contenu du presse-papiers dans un document quelconque.
# test.py
import pyperclip
pyperclip.copy("Ce texte est copié dans le presse-papiers")
print (pyperclip.paste())

3) Vérifier la présence du paquet tkinter

Tkinter (Toolkit interface) fait partie de la distribution standard de Python. C'est un module qui permet de créer des programmes Python dotés d’une interface graphique utilisateur (GUI). Pour vérifier que tkinter est correctement installé on tape, dans le terminal de commande, l'une des commandes python suivantes:
python -m tkinter
python3 -m tkinter

Si tkinter est bien installé, un message du type "This is Tcl/Tk version 8.6" nous est retourné.

03

Normalement tkinter est inclus dans toutes les distributions standard de Python depuis la version 3.1. Si tkinter n'est pas installé, la solution la plus simple consiste donc à installer (ou à réinstaller entièrement) une version récente de Python qui intégrera de fait tkinter.

Le programme test.py suivant permet de vérifier le bon fonctionnement de tkinter.
# test.py - test du module tkinter
from tkinter import Tk, Label
fenetre =Tk()
fenetre.geometry("200x100")
texte = Label(fenetre, text= "Bonjour !")
texte.pack()
fenetre.mainloop()

4) Vérifier la présence d'un IDE Python

On peut vérifier la présence d'un environnement de développement intégré (IDE) pour Python (l'IDE Thonny par exemple) en examinant la liste des applications depuis le bureau Gnome (bouton "Afficher les applications") ou en tapant la commande suivante:
pip3 list

04

Si thonny n'est pas déjà installé, on l'installe à l'aide des commandes suivantes :
sudo apt update
sudo apt install thonny

5) Créer le programme

On copie puis on adapte à nos besoins le programme source ctclipbord.py (Copy To Clipboard) suivant :
ctclipboard.py

Ce programme fonctionne de la façon suivante :

  • Quand on clique un bouton de commande, le texte correspondant est inséré dans la zone de texte, à la suite du texte qui s'y trouve déjà;
  • Quand on clique le bouton de commande Copy, le contenu de la zone de texte est copié dans le presse-papiers. On peut ensuite le récupérer dans n'importe quel document à l'aide d'un Ctrl+V;
  • Quand on clique le bouton de commande Clear, le contenu de la zone de texte est effacé.
Remarque : la zone de texte peut également être éditée directement.

05

# ---------------------------------------------
# Programme python : ctclipboard.py
# Copie rapide de mots dans le presse-papiers
# Claude Turrier - 25 octobre 2020
#--------------------------------------------
import pyperclip
from tkinter import *
#--------FONCTIONS---------
def f1(): x=var; c="Charles, "; x.set(x.get()+c)
def f2(): x=var; c="Fernande, "; x.set(x.get()+c)
def f3(): x=var; c="Françoise, "; x.set(x.get()+c)
def f4(): x=var; c="Georgette, "; x.set(x.get()+c)
def f5(): x=var; c="Hélène, "; x.set(x.get()+c)
def f6(): x=var; c="Jeanne, "; x.set(x.get()+c)
def f7(): x=var; c="Marie Laure, "; x.set(x.get()+c)
def f8(): x=var; c="Pierre, "; x.set(x.get()+c)
def f9(): x=var; c="Vincent, "; x.set(x.get()+c)
def f10(): x=var; c="Dupond, "; x.set(x.get()+c)

def f11(): x=var; c="Charles "; x.set(x.get()+c)
def f12(): x=var; c="Fernande "; x.set(x.get()+c)
def f13(): x=var; c="Françoise "; x.set(x.get()+c)
def f14(): x=var; c="Georgette "; x.set(x.get()+c)
def f15(): x=var; c="Hélène "; x.set(x.get()+c)
def f16(): x=var; c="Jeanne "; x.set(x.get()+c)
def f17(): x=var; c="Marie Laure "; x.set(x.get()+c)
def f18(): x=var; c="Pierre "; x.set(x.get()+c)
def f19(): x=var; c="Vincent "; x.set(x.get()+c)
def f20(): x=var; c="Dupond "; x.set(x.get()+c)

def f31(): x=var; c="Gaby, "; x.set(x.get()+c)
def f32(): x=var; c="Germaine, "; x.set(x.get()+c)
def f33(): x=var; c="Jeannie, "; x.set(x.get()+c)
def f34(): x=var; c="Jean, "; x.set(x.get()+c)
def f35(): x=var; c="Madeleine, "; x.set(x.get()+c)
def f36(): x=var; c="Maurice, "; x.set(x.get()+c)
def f37(): x=var; c="Raymond, "; x.set(x.get()+c)
def f38(): x=var; c="Roger, "; x.set(x.get()+c)
def f39(): x=var; c="Yvette, "; x.set(x.get()+c)
def f40(): x=var; c="Dubois, "; x.set(x.get()+c)
def f41(): x=var; c="Durand, "; x.set(x.get()+c)
def f42(): x=var; c="Martin, "; x.set(x.get()+c)

def f51(): x=var; c="Gaby "; x.set(x.get()+c)
def f52(): x=var; c="Germaine "; x.set(x.get()+c)
def f53(): x=var; c="Jeannie "; x.set(x.get()+c)
def f54(): x=var; c="Jean "; x.set(x.get()+c)
def f55(): x=var; c="Madeleine "; x.set(x.get()+c)
def f56(): x=var; c="Maurice "; x.set(x.get()+c)
def f57(): x=var; c="Raymond "; x.set(x.get()+c)
def f58(): x=var; c="Roger "; x.set(x.get()+c)
def f59(): x=var; c="Yvette "; x.set(x.get()+c)
def f60(): x=var; c="Dubois "; x.set(x.get()+c)
def f61(): x=var; c="Durand "; x.set(x.get()+c)
def f62(): x=var; c="Martin "; x.set(x.get()+c)

def f99(): x=var; pyperclip.copy(x.get())
def f100(): x=var; x.set("") # bouton C(lear )
def f101(): x=var; c="de g à d, "; x.set(x.get()+c)
def f102(): x=var; c="1er rang, "; x.set(x.get()+c)
def f103(): x=var; c="2ème rang, "; x.set(x.get()+c)
def f104(): x=var; c="devant, "; x.set(x.get()+c)
def f105(): x=var; c="au fond, "; x.set(x.get()+c)
def f106(): x=var; c=": "; x.set(x.get()+c)
def f107(): x=var; c=", "; x.set(x.get()+c)
#def f107(): var.set(eval(var.get()))
#--------FENETRE DU PROGRAMME---------
fenetre = Tk()
fenetre.title("CT Clipboard")
fenetre.geometry("1600x200")
fenetre.resizable(width=False, height=False)
#--------ZONE DE SAISIE-------
var = StringVar()
E=Entry(fenetre, relief=SUNKEN, textvariable=var)
E.pack(expand=YES, fill=BOTH)
#-------FRAMES---------------
F1 = Frame(fenetre, bd=2, bg=""); F1.pack(expand=YES, fill=BOTH)
F2 = Frame(fenetre, bd=2, bg=""); F2.pack(expand=YES, fill=BOTH)
F3 = Frame(fenetre, bd=2, bg=""); F3.pack(expand=YES, fill=BOTH)
F4 = Frame(fenetre, bd=2, bg=""); F4.pack(expand=YES, fill=BOTH)
F5 = Frame(fenetre, bd=2, bg="black"); F5.pack(expand=YES, fill=BOTH)
#---------BOUTONS DE COMMANDE---------
#Création des boutons

B1=Button(F1, text="Charles,", command=f1);
B2=Button(F1, text="Fernande,", command=f2);
B3=Button(F1, text="Françoise,", command=f3);
B4=Button(F1, text="Georgette,", command=f4);
B5=Button(F1, text="Hélène,", command=f5);
B6=Button(F1, text="Jeanne,", command=f6);
B7=Button(F1, text="Marie laure,", command=f7);
B8=Button(F1, text="Pierre,", command=f8);
B9=Button(F1, text="Vincent,", command=f9);
B10=Button(F1, text="Dupond,", command=f10);

B11=Button(F2, text="Charles ", command=f11);
B12=Button(F2, text="Fernande ", command=f12);
B13=Button(F2, text="Françoise ", command=f13);
B14=Button(F2, text="Georgette ", command=f14);
B15=Button(F2, text="Hélène ", command=f15);
B16=Button(F2, text="Jeanne ", command=f16);
B17=Button(F2, text="Marie laure ", command=f17);
B18=Button(F2, text="Pierre ", command=f18);
B19=Button(F2, text="Vincent ", command=f19);
B20=Button(F2, text="Dupond ", command=f20);

B31=Button(F3, text="Gaby, ", command=f31);
B32=Button(F3, text="Germaine, ", command=f32);
B33=Button(F3, text="Jeannie, ", command=f33);
B34=Button(F3, text="Jean, ", command=f34);
B35=Button(F3, text="Madeleine, ", command=f35);
B36=Button(F3, text="Maurice, ", command=f36);
B37=Button(F3, text="Raymond, ", command=f37);
B38=Button(F3, text="Roger, ", command=f38);
B39=Button(F3, text="Yvette, ", command=f39);
B40=Button(F3, text="Dubois, ", command=f40);
B41=Button(F3, text="Durand, ", command=f41);
B42=Button(F3, text="Martin, ", command=f42);
B51=Button(F4, text="Gaby ", command=f51);
B52=Button(F4, text="Germaine ", command=f52);
B53=Button(F4, text="Jeannie ", command=f53);
B54=Button(F4, text="Jean ", command=f54);
B55=Button(F4, text="Madeleine ", command=f55);
B56=Button(F4, text="Maurice ", command=f56);
B57=Button(F4, text="Raymond ", command=f57);
B58=Button(F4, text="Roger ", command=f58);
B59=Button(F4, text="Yvette ", command=f59);
B60=Button(F4, text="Dubois ", command=f60);
B61=Button(F4, text="Durand ", command=f61);
B62=Button(F4, text="Martin ", command=f62);
B99=Button(F5, text="Copy", command=f99);
B100=Button(F5, text="Clear", command=f100);
B101=Button(F5, text="de g à d,", command=f101);
B102=Button(F5, text="1er rang,", command=f102);
B103=Button(F5, text="2ème rang, ", command=f103);
B104=Button(F5, text="devant, ", command=f104);
B105=Button(F5, text="au fond, ", command=f105);
B106=Button(F5, text=" : ", command=f106);
B107=Button(F5, text=" , ", command=f107);
#Affichage des boutons
B1.pack(side=LEFT, expand=YES, fill=BOTH)
B2.pack(side=LEFT, expand=YES, fill=BOTH)
B3.pack(side=LEFT, expand=YES, fill=BOTH)
B4.pack(side=LEFT, expand=YES, fill=BOTH)
B5.pack(side=LEFT, expand=YES, fill=BOTH)
B6.pack(side=LEFT, expand=YES, fill=BOTH)
B7.pack(side=LEFT, expand=YES, fill=BOTH)
B8.pack(side=LEFT, expand=YES, fill=BOTH)
B9.pack(side=LEFT, expand=YES, fill=BOTH)
B10.pack(side=LEFT, expand=YES, fill=BOTH)

B11.pack(side=LEFT, expand=YES, fill=BOTH)
B12.pack(side=LEFT, expand=YES, fill=BOTH)
B13.pack(side=LEFT, expand=YES, fill=BOTH)
B14.pack(side=LEFT, expand=YES, fill=BOTH)
B15.pack(side=LEFT, expand=YES, fill=BOTH)
B16.pack(side=LEFT, expand=YES, fill=BOTH)
B17.pack(side=LEFT, expand=YES, fill=BOTH)
B18.pack(side=LEFT, expand=YES, fill=BOTH)
B19.pack(side=LEFT, expand=YES, fill=BOTH)
B20.pack(side=LEFT, expand=YES, fill=BOTH)

B31.pack(side=LEFT, expand=YES, fill=BOTH)
B32.pack(side=LEFT, expand=YES, fill=BOTH)
B33.pack(side=LEFT, expand=YES, fill=BOTH)
B34.pack(side=LEFT, expand=YES, fill=BOTH)
B35.pack(side=LEFT, expand=YES, fill=BOTH)
B36.pack(side=LEFT, expand=YES, fill=BOTH)
B37.pack(side=LEFT, expand=YES, fill=BOTH)
B38.pack(side=LEFT, expand=YES, fill=BOTH)
B39.pack(side=LEFT, expand=YES, fill=BOTH)
B40.pack(side=LEFT, expand=YES, fill=BOTH)
B41.pack(side=LEFT, expand=YES, fill=BOTH)
B42.pack(side=LEFT, expand=YES, fill=BOTH)

B51.pack(side=LEFT, expand=YES, fill=BOTH)
B52.pack(side=LEFT, expand=YES, fill=BOTH)
B53.pack(side=LEFT, expand=YES, fill=BOTH)
B54.pack(side=LEFT, expand=YES, fill=BOTH)
B55.pack(side=LEFT, expand=YES, fill=BOTH)
B56.pack(side=LEFT, expand=YES, fill=BOTH)
B57.pack(side=LEFT, expand=YES, fill=BOTH)
B58.pack(side=LEFT, expand=YES, fill=BOTH)
B59.pack(side=LEFT, expand=YES, fill=BOTH)
B60.pack(side=LEFT, expand=YES, fill=BOTH)
B61.pack(side=LEFT, expand=YES, fill=BOTH)
B62.pack(side=LEFT, expand=YES, fill=BOTH)

B99.pack(side=LEFT, expand=YES, fill=BOTH)
B100.pack(side=LEFT, expand=YES, fill=BOTH)
B101.pack(side=LEFT, expand=YES, fill=BOTH)
B102.pack(side=LEFT, expand=YES, fill=BOTH)
B103.pack(side=LEFT, expand=YES, fill=BOTH)
B104.pack(side=LEFT, expand=YES, fill=BOTH)
B105.pack(side=LEFT, expand=YES, fill=BOTH)
B106.pack(side=LEFT, expand=YES, fill=BOTH)
B107.pack(side=LEFT, expand=YES, fill=BOTH)
#---BOUCLE EVENEMENTIELLE DU PROGRAMME---
fenetre.mainloop()
#---------------------