#!/usr/bin/python3 # -*- coding: utf-8 -*- ''' tablette_set.py Le but est de régler les paramètres de la tablette XP-pen star 04, ầ notre convenance. ° Région d'écran correspondant à la tablette ° Positionnement relatif ou absolut ° Gestion des boutons. Références : https://tkdocs.com/shipman/ # Documentation sur tkinter, avec une grande table des matières. https://realpython.com/python-gui-tkinter/ # méthodes pack(), place() et grid() http://tkinter.fdex.eu/doc/uwm.html#bind_all https://effbot.org/tkinterbook/tkinter-events-and-bindings.htm http://tkinter.fdex.eu/doc/event.html Événements: répondre aux actions de l'utilisateur. https://www.pythontutorial.net/tkinter/tkinter-grid/ https://www.pythontutorial.net/tkinter/tkinter-ttk/ Livres et Web : 1) Automate the boring stuff with python, practical programming for total beginners, de Al Sweigart edition : no starch press, 2nd edition, 2020 2) Modern Tkinter for Busy Python Developers, (for Windows, Mac and Linux) de Mark Roseman, edition Late Afternoon Press, third edition, 2020 3) https://tcl.tk/man/tcl8.6/TkCmd/contents.htm °) Il y a trop de références Web, pour les mettre ici. Ce logiciel est mise à disposition sous la licence GPL version 3 (GNU General Public License version 3) En gros, cela signifie que vous avez les quatre libertés fondamentales du logiciel libre : 0) la liberté d'utiliser le logiciel 1) la liberté de copier le logiciel 2) la liberté d'étudier le logiciel 3) la liberté de modifier le logiciel et de redistribuer les versions modifiées, sous les mêmes conditions Mais 4) vous ne pouvez pas vous l'approprier. !) il appartient à la communauté du monde libre. c.f. : https://www.gnu.org/licenses/license-list.html ''' from tkinter import * import pyautogui as gui import subprocess def Info_button1(): #=================== # Affiche de l'information sur les champs de la même ligne. global txt2 strInfo = "Information sur le bouton 1.\n"\ 'Plus d\'info.' if (txt2 == 0): print("cocou") txt2.delete(0.0, END) txt2.insert(0.0, strInfo) # ligne.colonne ou INSERT ou END def Delete_fen2(): #================= # Ferme la fenêtre de gestion des boutons. global fen2 if (not 'fen2' in globals()): fen2 = 0 #Sinon Thonny reporte une erreur incorrectement. #print("Dans Delete_fen2, fermeture de fen2", type(fen2)) fen2loc = fen2 fen2 = 0 fen2loc.destroy() def Delete_fen2_esc(event): #========================== #pylint: disable=unused-argument Delete_fen2() def Is_fen2_open(): #================== # Retourne True si la fen2 est ouverte, False sinon return fen2 != 0 def Open_window_button_manager(fen1): #==================================== # Ouvre une fenêtre de gestion des boutons # Le code se trouve dans un autre fichier # c.f. https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/toplevel.html global fen2, txt2 if (fen2 != 0): # La fenêtre est déjà ouverte, met-la au premier plan #fen2.grab_set() #print(fen2.focus_displayof()) # Y a-t-il un bug de python sous Linux, que le focus ne va pas automatiquement à fen2 # lorsque fen2 passe devant fen1 ??? fen2.lift(fen1) # Le focus reste sur la fen1 !?! #fen1.lower(fen2) # équivalent à fen2.lift(fen1) #fen2.focus_set() #fen2.focus_force() #fen2.attributes('-topmost', True) #fen2.iconify() #fen2.update() #fen2.deiconify() return #fen2 = Tk() fen2 = Toplevel(fen1) fen2.takefocus = True #fen2.transient(fen1) # Utilité ??? #fen2.attributes('-topmost', True) #fen2 reste devant fen1, mais ne l'empêche pas d'avoir le focus. #fen2.grab_set() # Si appelé, empêche la fenêtre parente de recevoir des messages. fen2.title("Paramétrage des boutons de la tablette.") # Permet de positionner la fenêtre sur l'écran #fen1.wm_geometry("+%d+%d" % (400, 100)) # Définit la position de la fenêtre. # Pour définir également la dimension : largeur=730; hauteur=650; xpos=100; ypos=100 fen2.wm_geometry("%dx%d+%d+%d" % (largeur, hauteur, xpos, ypos)) # Deux "Frame", pour la mise en fenêtre. frame1s = Frame(fen2, borderwidth=2, relief="sunken") # grove ridge sunken flat solid raised frame1s.grid(row=0, column=0, sticky=W) frame2s = Frame(fen2, borderwidth=2, relief="sunken") frame2s.grid(row=1, column=0, sticky=W) row_sel = 0 # https://www.tutorialspoint.com/python/tk_entry.htm Button(frame1s, text='?', command=Info_button1).grid(row=row_sel, column=0, stick=W) Label(frame1s, text ='Bouton ').grid(row=row_sel, column = 1, sticky=W) Label(frame1s, text ='Touche ').grid(row=row_sel, column = 2, sticky=W) Label(frame1s, text ='Autre ').grid(row=row_sel, column = 3, sticky=W) Label(frame1s, text ='À effacer ').grid(row=row_sel, column = 4, sticky=W) row_sel += 1 Button(frame1s, text='?', command=Info_button1).grid(row=row_sel, column=0, stick=W) Label(frame1s, text ='Un texte :').grid(row=row_sel, column = 1, sticky=W) entr_button1 = Entry(frame1s, width=36, bg="white") entr_button1.grid(row= row_sel, column = 2, columnspan=3, sticky=W) entr_button1.insert(0, "À voir...") row_sel += 1 # Création du bouton pour quitter btnClose2 = Button(fen2, text='Fermer', command=Delete_fen2) btnClose2.grid(row=1, column=1, stick=SE) row_sel += 1 txt2 = Text(fen2, width=90, height=15, bg="white") # , state=DISABLED txt2.grid(row=3, column=0, columnspan=2, stick=W) # Placé et positionné correctement. #txt2.place(x = 2, y=200, width=600, height=90) # Sera replacé et dimensionné correctement row_sel += 1 strInfo = "\n En cours de développement, il reste beaucoup à faire ici..." txt2.insert(0.0, strInfo) # ligne.colonne ou INSERT ou END #fen2.bind("", lambda x: fen2.destroy()) # ferme la fenêtre en pressant sur la touche Esc fen2.bind("", Delete_fen2_esc) # ferme la fenêtre en pressant sur la touche Esc fen2.protocol("WM_DELETE_WINDOW", Delete_fen2) # Juste pour que ces variables soient définies. fen2 = 0 txt2 = 0 ############################################################################### ############################################################################### def Delete_fen1(): #================= # Ferme la fenêtre de gestion des boutons. #global fen1, fen2 if Is_fen2_open(): Delete_fen2() # On ferme aussi la fenêtre 1 fen1.quit() def Delete_fen1_esc(event): #========================== #pylint: disable=unused-argument Delete_fen1() def Information(strName): #======================== # Affiche de l'information sur les champs de la même ligne. if (strName == "pad"): strInfo = "Indique le nom de la tablette.\n"\ 'Cela peut se vérifier en cliquant sur le bouton "List devices"' elif (strName == "pen"): strInfo = "Indique le nom du stylo.\n"\ 'Cela peut se vérifier en cliquant sur le bouton "List devices"' elif (strName == "eraser"): strInfo = "Indique le nom de la gomme, si elle existe.\n"\ 'Cela peut se vérifier en cliquant sur le bouton "List devices"' elif (strName == "resolution"): strInfo = "Les nombres de pixels horizontalement et verticalement de(s) écran(s).\n"\ "Ils sont détectés automatiquement.\n"\ "Un standard est : 1920 x 1080." elif (strName == "tabxymax"): strInfo = "Indique les coordonnées des valeurs maximales en X et Y de la tablette.\n"\ "Est obtenu en analysant ce qui est retourné par l'instruction :\n"\ 'xinput list --long "Nom du stylo"\n'\ "X=15200 Y= 9500 pour la Wacom Intuos S\n"\ "X=45720 Y=29210 pour la XP pen star 04\n" txt1.delete(0.0, END) txt1.insert(0.0, strInfo) # ligne.colonne ou INSERT ou END def Info_set_correspondance(Num): #================================ # Affiche de l'information sur les champs de la même ligne et de la ligne suivante et du bouton. if (Num == 1): strInfo = '1) Cliquer sur le bouton "Get Top-Left".\n'\ "2) Déplacer la souris sur la position de l'écran\n"\ " qui devra correspondre à la position haut- gauche de la tablette.\n"\ "3) Appuyez sur la barre d'espace.\n" if (Num == 2): strInfo = '1) Cliquer sur le bouton "Get Bottom-Right".\n'\ "2) Déplacer la souris sur la position de l'écran\n"\ " qui devra correspondre à la position haut- gauche de la tablette.\n"\ "3) Appuyez sur la barre d'espace.\n\n"\ '4) Cliquez sur le bouton "Set correspondance Tablette - Ecran"\n'\ " pour établir la correspondance désirée." if (Num == 3): strInfo = 'Si le mode est "Relative", la tablette se comporte comme un "touch pad".\n'\ 'Le bouton "Set correspondance Tablette - Ecran" règle la sensibilité.\n\n'\ 'Si le mode est "Absolute",\n'\ "il y aura une correspondance fixe entre les positions sur la tablette et sur l'écran." txt1.delete(0.0, END) txt1.insert(0.0, strInfo) # ligne.colonne ou INSERT ou END def Button_manager(): #==================== # Ouvre une fenêtre de gestion des boutons # Le code se trouve dans un autre fichier Open_window_button_manager(fen1) def pointeur1(event): #=================== #pylint: disable=unused-argument entr1x.delete(0,END) entr1x.insert(0, str(gui.position().x)) entr1y.delete(0,END) entr1y.insert(0, str(gui.position().y)) b1.unbind_all("") def pointeur2(event): #=================== #pylint: disable=unused-argument entr2x.delete(0,END) entr2x.insert(0, str(gui.position().x)) entr2y.delete(0,END) entr2y.insert(0, str(gui.position().y)) b2.unbind_all("") def Bind_pointeur1(): #==================== b1.bind_all("", pointeur1) # En pressant sur la barre d'espace, les champs sont mis à jours def Bind_pointeur2(): #==================== b2.bind_all("", pointeur2) # En pressant sur la barre d'espace, les champs sont mis à jours def Action3(): #============= # Juste un Exemple. # Exécute une commande shell #result = subprocess.run(["ls", "-l", "/home/bg/Bg2"], capture_output=True, text=True) # BIEN # c.f. https://www.digitalocean.com/community/tutorials/how-to-use-subprocess-to-run-external-programs-in-python-3-fr #result = subprocess.call("ls", shell=True) #result = subprocess.call(["echo", "hello world"], stdout=subprocess.PIPE) result = subprocess.run("ls -l ./", shell=True, capture_output=True, text=True) #print(result.stdout) txt1.delete(0.0, END) txt1.insert(0.0, result.stdout) # ligne.colonne INSERT ou END def List_devices(): #============= # List les tablettes présentes result = subprocess.run("xsetwacom --list devices", shell=True, capture_output=True, text=True) #print(result.stdout) txt1.delete(0.0, END) txt1.insert(0.0, result.stdout) # ligne.colonne ou INSERT ou END def GetVal(strIn, strDefault, strS1, strS2, strS3, strS4): #========================================================= # Pour la gestion des string C.f. https://www.w3schools.com/python/python_strings_methods.asp # Extraction du nombre entier qui se trouve dans la chaîne strIn, # après strS1 et strS2 et entre la fin de strS3 et ce qui précède strS4. # Valeurs typique : GetVal(result.stdout, "Abs X", "Range", " - ", ".") # strDefault est la valeur retournée par défaut, si pas trouvé ce qui est cherché strVal = strDefault # Au cas où ce qui est cherché n'a pas été trouvé n1 = strIn.find(strS1) if (n1 <= 0): return strVal strIn = strIn[n1:len(strIn)] n1 = strIn.find(strS2) if (n1 <= 0): return strVal strIn = strIn[n1:len(strIn)] n1 = strIn.find(strS3) if (n1 <= 0): return strVal strIn = strIn[n1:len(strIn)] n2 = strIn.find(strS4) if (n2 <= len(strS3)): return strVal strVal = strIn[len(strS3):n2] # Saute la chaîne strS3 ( " - " ) return strVal def Set_names(): #=============== # Lit les noms de la tablette, du stylo et de la gomme # Lit également les dimensions utilisées par la tablette. strPen_name = "///" strEraser_name = "///" strPad_name = "///" result = subprocess.run("xsetwacom --list devices", shell=True, capture_output=True, text=True) #print("." + result.stdout + ".") listall = result.stdout.split("\n") # Cherche les noms des objets, STYLUS ou ERASER ou PAD for nn in range(len(listall)-1): sublist = listall[nn].split("\t") strName = sublist[0].rstrip() # enlève les blancs en fin du nom de l'objet if (sublist[2].find("STYLUS") > 0): strPen_name = strName if (sublist[2].find("ERASER") > 0): strEraser_name = strName if (sublist[2].find("PAD") > 0): strPad_name = strName entr_pad_name.delete(0, END) entr_pad_name.insert(0, strPad_name) entr_pen_name.delete(0, END) entr_pen_name.insert(0, strPen_name) entr_eraser_name.delete(0, END) entr_eraser_name.insert(0, strEraser_name) # Lecture des dimensions retournées par la tablette result = subprocess.run('xinput list --long "' + entr_pen_name.get() + '"', shell=True, capture_output=True, text=True) strVal = GetVal(result.stdout, "45720", "Abs X", "Range", " - ", ".") entr3x.delete(0, END) entr3x.insert(0, strVal) # Valeur de nPad_xmax, X max de la tablette strVal = GetVal(result.stdout, "29210", "Abs Y", "Range", " - ", ".") entr3y.delete(0, END) entr3y.insert(0, strVal) # Valeur de nPad_xmax, X max de la tablette def Get_all_param(Num): #====================== # List de tous les paramètres du "Pen stylus" ou du "Pad pad" txt1.delete(0.0, END) if (Num == 1): strCmd = 'xsetwacom --get "' + entr_pad_name.get() + '" all' txt1.insert(0.0, "Pad (tablette), paramètres:\n") # ligne.colonne ou INSERT ou END elif (Num == 2): strCmd = 'xsetwacom --get "' + entr_pen_name.get() + '" all' txt1.insert(0.0, "Pen (stylo), paramètres:\n") # ligne.colonne ou INSERT ou END elif (Num == 3): strCmd = 'xsetwacom --get "' + entr_eraser_name.get() + '" all' txt1.insert(0.0, "Eraser (gomme), paramètres:\n") # ligne.colonne ou INSERT ou END elif (Num == 11): strCmd = 'xinput list --long "' + entr_pad_name.get() + '"' txt1.insert(0.0, "Pad (tablette), paramètres:\n") # ligne.colonne ou INSERT ou END elif (Num == 12): strCmd = 'xinput list --long "' + entr_pen_name.get() + '"' txt1.insert(0.0, "Pen (stylo), paramètres:\n") # ligne.colonne ou INSERT ou END elif (Num == 13): strCmd = 'xinput list --long "' + entr_eraser_name.get() + '"' txt1.insert(0.0, "Eraser (gomme), paramètres:\n") # ligne.colonne ou INSERT ou END else: strCmd = "xsetwacom --help" # Par défaut, en cas d'erreur de programmation result = subprocess.run(strCmd, shell=True, capture_output=True, text=True) #print(result.stdout) txt1.insert(END, strCmd + "\n") # ligne.colonne ou INSERT ou END txt1.insert(END, result.stdout + "\n") # ligne.colonne ou INSERT ou END txt1.insert(END, result.stderr) # ligne.colonne ou INSERT ou END def Set_correspondance(): #======================== # Définit la correspondance entre la tablette XP pen star 04 et la région d'écran nRes_x = int(entr0x.get()) nRes_y = int(entr0y.get()) nLeft = int(entr1x.get()) nRight = int(entr2x.get()) nTop = int(entr1y.get()) nBottom = int(entr2y.get()) nPad_xmax = int(entr3x.get()) nPad_ymax = int(entr3y.get()) strMode = glstrMode.get() # La correspondance change, suivant que l'on soit en mode "relative" ou "abslut" #strCmd = 'xsetwacom --get "' + entr_pen_name.get() + '" Mode' #result = subprocess.run(strCmd, shell=True, capture_output=True, text=True) #strMode = result.stdout #print("." + strMode[0:8] + ".") strCmd = 'xsetwacom --set "' + entr_pen_name.get() + '" Mode ' + strMode[0:8] #result = \ subprocess.run(strCmd, shell=True, capture_output=True, text=True) #print(result.stdout); print(result.stderr) txdelta = nRight - nLeft if txdelta == 0: txdelta = 10 tydelta = nBottom - nTop if tydelta == 0: tydelta = 10 if (strMode[0:8] == "Relative"): # En mode "Relative", la sensibilité est plus grande, elle est donc diminuée ici. txdelta /= 2 tydelta /= 4 # 45720 = droite de la tablette XP-pen star 04 # 15200 = droite de la tablette Wacom Intuos S txmin = int(-nPad_xmax * nLeft / txdelta) txmax = int( nPad_xmax * (nRes_x - nLeft) / txdelta) # 29210 = bas de la tablette XP-pen star 04 # 9500 = bas de la tablette Wacom Intuos S tymin = int(-nPad_ymax * nTop / tydelta) tymax = int( nPad_ymax * (nRes_y - nTop) / tydelta) strCmd = 'xsetwacom --set "' + entr_pen_name.get() + '" Area ' + \ str(txmin) + " " + str(tymin) + " " + str(txmax) + " " + str(tymax) #result = \ subprocess.run(strCmd, shell=True, capture_output=True, text=True) #print(result.stdout); print(result.stderr) txt1.delete(0.0, END) # ligne.colonne ou INSERT ou END txt1.insert(0.0, strCmd) # ligne.colonne ou INSERT ou END txt1.insert(END, "\nA été envoyé au shell pour la correspondance désirée.") txt1.insert(END, "\n\nMode = " + strMode) ''' def GetMode(): #============= # Lit le mode de la tablette, Absolue ou Relative strCmd = 'xsetwacom --get "' + entr_pen_name.get() + '" Mode' result = subprocess.run(strCmd, shell=True, capture_output=True, text=True) #print(result.stdout) txt1.delete(0.0, END) txt1.insert(0.0, "Mode = " + result.stdout) # ligne.colonne ou INSERT ou END, CURRENT, SEL_FIRST, SEL_LAST def SetMode(strMode): #==================== # La correspondance entre la tablette et l'écran est en positions "Relative" ou "Absolute" strCmd = 'xsetwacom --set "' + entr_pen_name.get() + '" Mode ' + strMode #result = \ subprocess.run(strCmd, shell=True, capture_output=True, text=True) #print(result.stdout); print(result.stderr) GetMode() ''' def Window_resise(event): #======================== #pylint: disable=unused-argument # Est appelé à chaque modification de la taille de la fenêtre. # Repositionne le texte en fonction de la taille de la fenêtre. # C.f. https://tkdocs.com/shipman/universal.html #large, hauteur = event.width, event.height # Largeur et hauteur du canvas #print(txt1.winfo_geometry(), txt1.winfo_rootx(), txt1.winfo_rooty()) # BIEN #txt1.config(height = int((fen1.winfo_height() - txt1.winfo_y()) / 19)) txt1.place(x = 2, y=btnQuit.winfo_y() + btnQuit.winfo_height() + 1,\ width=fen1.winfo_width()-4, height=int(fen1.winfo_height() - txt1.winfo_y())) btnQuit.place(x=fen1.winfo_width() - btnQuit.winfo_width(), y=btnQuit.winfo_y()) # repositionne le bouton quit glScreen_res = gui.size() # Résolution de l'écran # Positions de l'écran correspondant à la Tablette. glnLeft = 0 glnTop = 0 glnRight = glScreen_res.width glnBottom = glScreen_res.height fen1 = Tk() fen1.title("Paramétrage de la tablette.") # Pour le OptionMenu glstrMode = StringVar() glstrMode.set("Absolute") # Permet de positionner la fenêtre sur l'écran #fen1.wm_geometry("+%d+%d" % (400, 100)) # Définit la position de la fenêtre. # Pour définir également la dimension : largeur=820; hauteur=650; xpos=400; ypos=100 fen1.wm_geometry("%dx%d+%d+%d" % (largeur, hauteur, xpos, ypos)) # Deux "Frame", pour la mise en fenêtre. frame1 = Frame(fen1, borderwidth=2, relief="sunken") # grove ridge sunken flat solid raised frame1.grid(row=0, column=0, sticky=W) frame2 = Frame(fen1, borderwidth=2, relief="sunken") frame2.grid(row=1, column=0, sticky=W) row_sel = 0 # https://www.tutorialspoint.com/python/tk_entry.htm Button(frame1, text='?', command=lambda arg="pad": Information(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Nom de tablette :').grid(row=row_sel, column = 1, sticky=W) entr_pad_name = Entry(frame1, width=36, bg="white") entr_pad_name.grid(row= row_sel, column = 2, columnspan=3, sticky=W) entr_pad_name.insert(0, "UGTABLET TABLET G5 9x6 Pad pad") Button(frame1, text='Param ?', command=lambda arg=1: Get_all_param(arg)).grid(row=row_sel, column=5, stick=W) Button(frame1, text='+ ?', command=lambda arg=11: Get_all_param(arg)).grid(row=row_sel, column=6, stick=W) row_sel += 1 Button(frame1, text='?', command=lambda arg="pen": Information(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Nom du stylo :').grid(row=row_sel, column = 1, sticky=W) entr_pen_name = Entry(frame1, width=36, bg="white") entr_pen_name.grid(row= row_sel, column = 2, columnspan=3, sticky=W) entr_pen_name.insert(0, "UGTABLET TABLET G5 9x6 Pen stylus") Button(frame1, text='Param ?', command=lambda arg=2: Get_all_param(arg)).grid(row=row_sel, column=5, stick=W) Button(frame1, text='+ ?', command=lambda arg=12: Get_all_param(arg)).grid(row=row_sel, column=6, stick=W) row_sel += 1 Button(frame1, text='?', command=lambda arg="eraser": Information(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Nom de la gomme :').grid(row=row_sel, column = 1, sticky=W) entr_eraser_name = Entry(frame1, width=36, bg="white") entr_eraser_name.grid(row= row_sel, column = 2, columnspan=3, sticky=W) entr_eraser_name.insert(0, "xxx") Button(frame1, text='Param ?', command=lambda arg=3: Get_all_param(arg)).grid(row=row_sel, column=5, stick=W) Button(frame1, text='+ ?', command=lambda arg=13: Get_all_param(arg)).grid(row=row_sel, column=6, stick=W) row_sel += 1 Button(frame1, text='?', command=lambda arg="resolution": Information(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Résolution X, Y :').grid(row=row_sel, column = 1, sticky=W) entr0x = Entry(frame1, width=6, bg="white") entr0x.grid(row= row_sel, column = 2, sticky=W) entr0y = Entry(frame1, width=6, bg="white") entr0y.grid(row= row_sel, column = 3, sticky=W) entr0x.insert(0, str(glScreen_res.width)) entr0y.insert(0, str(glScreen_res.height)) row_sel += 1 Button(frame1, text='?', command=lambda arg="tabxymax": Information(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Tablette Xmax, Ymax :').grid(row=row_sel, column = 1, sticky=W) entr3x = Entry(frame1, width=6, bg="white") entr3x.grid(row= row_sel, column = 2, sticky=W) entr3y = Entry(frame1, width=6, bg="white") entr3y.grid(row= row_sel, column = 3, sticky=W) entr3x.insert(0, str(15200)) entr3y.insert(0, str( 9500)) row_sel += 1 Button(frame1, text='?', command=lambda arg=1: Info_set_correspondance(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Pos. gauche haut :').grid(row=row_sel, column=1, sticky=W) entr1x = Entry(frame1, width=6, bg="white") entr1x.grid(row= row_sel, column = 2, sticky=W) entr1x.insert(0, str(glnLeft)) entr1y = Entry(frame1, width=6, bg="white") entr1y.grid(row= row_sel, column = 3, sticky=W) entr1y.insert(0, str(glnTop)) b1 = Button(frame1, text='Get Top-Left', command=Bind_pointeur1) b1.grid(row=row_sel, column=4, stick=W) row_sel += 1 Button(frame1, text='?', command=lambda arg=2: Info_set_correspondance(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Pos. droite, bas :').grid(row=row_sel, column=1, sticky=W) entr2x = Entry(frame1, width=6, bg="white") entr2x.grid(row=row_sel, column = 2, sticky=W) entr2x.insert(0, str(glnRight)) entr2y = Entry(frame1, width=6, bg="white") entr2y.grid(row=row_sel, column = 3, sticky=W) entr2y.insert(0, str(glnBottom)) b2 = Button(frame1, text='Get Bottom-Right', command=Bind_pointeur2) b2.grid(row=row_sel, column=4, stick=W) row_sel += 1 Button(frame1, text='?', command=lambda arg=3: Info_set_correspondance(arg)).grid(row=row_sel, column=0, stick=W) Label(frame1, text ='Mode :').grid(row=row_sel, column=1, sticky=W) optionmenu1 = OptionMenu(frame1, glstrMode, "Absolute", "Relative") optionmenu1.grid(row= row_sel, column=2, columnspan=3, sticky=W) row_sel += 1 Button(frame1, text='Set correspondance stylo de Tablette - Ecran', command=Set_correspondance).\ grid(row=row_sel, column=0, columnspan=4, stick=W) row_sel += 1 Button(frame1, text='A FAIRE... Set correspondance Gomme de Tablette - Ecran', command=Set_correspondance).\ grid(row=row_sel, column=0, columnspan=4, stick=W) row_sel += 1 # Création du bouton pour quitter btnButtons = Button(fen1, text='Gestion des boutons', command=Button_manager) btnButtons.grid(row=0, column=1) # Placements dans la "frame3" row_sel = 0 Label(frame2, text ='Pour des informations :', bg="#f0f0f0").grid(row=row_sel, column=0, columnspan=2, sticky=W) Button(frame2, text='List devices', command=List_devices).grid(row=row_sel, column=2, stick=W) #Button(frame3, text='ls -l ./', command=Action3).grid(row=row_sel, column=3, stick=E) # Pour des tests row_sel += 1 # Création du bouton pour quitter btnQuit = Button(fen1, text='Quitter', command=Delete_fen1) btnQuit.grid(row=1, column=1, stick=SE) row_sel += 1 txt1 = Text(fen1, width=90, height=15, bg="white") # , state=DISABLED txt1.grid(row=3, column=0, columnspan=2, stick=W) # Placé et positionné correctement. #txt1.place(x = 2, y=200, width=600, height=90) # Sera replacé et dimensionné correctement txt1.grid(row=3, column=0, sticky=(E, W, N, S)) # Placé et positionné correctement. txt1.columnconfigure(0, weight=2) fen1.rowconfigure(3, weight=3) fen1.columnconfigure(1, weight=3) # Alternative à fen1.rowconfigure() et fen1.columnconfigure() #fen1.bind("", Window_resise) # Appel de la fonction au redimentionnement de la fenêtre #fen1.bind("", lambda x: fen1.quit()) # Sort de l'application en pressant sur la touche Esc fen1.bind("", Delete_fen1_esc) # ferme la fenêtre en pressant sur la touche Esc # Si on ferme une fenêtre en cliquant sur la croix en haut à droite, appelle Delete_fen1 fen1.protocol("WM_DELETE_WINDOW", Delete_fen1) Set_names() # Nom de la tablette, du stylo et de la gomme si elle existe. fen1.mainloop() fen1.destroy() # destruction (fermeture) de la fenêtre