Tkinter et les Classes
Maintenant que vous avez maitrisé tkinter, nous allons maintenant entrer dans le cœur de la programmation orientée objet avec tkinter et les class. cette partie est sans nul doute la plus compliqué en programmation mais, dès que vous l'aurez maitrisé vous serez capable de rivaliser avec Facebook et YouTube.
Quel
est le problème :
Imaginez que vous soyez
convoqué par un restaurant pour écrire un programme qui va permettre d’afficher
le menu sur tablette et smartphone en fonction des catégories (entrée,
résistance, dessert). Le restaurant propose plus de 50 menus et vous devez
présenter chaque menu de la même manière en faisant ressortir sont types.
Comment faire alors ?
On peut bien écrire une
seule class Frame que l’on multipliera 50 fois et même plus à notre guise. On
pourra même en faire une centaine de copies identiques. Cela vous rappelle bien
les Class que l’on a vu dans le livre précédent « Devenez expert en Python
| les bases du langage de A à Z »
Et tous comme l’on a été
capable de créer plusieurs personnages à partir d’une seule class personnage,
il est aussi de créer plusieurs class de Widgets à partir d’un seul Widget.
Voyons comment
procéder :
Premier
code : créer les menus et les stocker
menu.py
"""creation
de la liste des 50 menus subdivisé en 15 entréés, 20 resistances,
et 15 desserts
"""
import os, pickle
import random
from random import
randrange
#définition des variables
typeDePlats=["éntrée","résistance","dessert"]
# chaque tuple
designe les prix d'un type de plats
prixDesPlats=[(1000, 500,
1500),(5000, 2500, 3000, 1500, 10000),
(1000, 500, 2000)]
platsEntree=[]
platsResistance=[]
platsDessert=[]
# remplissage des tables
for i in range(15):
ind=randrange(len(prixDesPlats[0])) # l'on obtient un indices nous permettant d'attribuer un prix
aux hazard au menu
platsEntree.append((typeDePlats[0],'plats entrée N-'+str(i),
prixDesPlats[0][ind]))
print(platsEntree)
for i in range(15):
ind=randrange(len(prixDesPlats[1])) # l'on obtient un indices nous permettant d'attribuer un
prix aux hazard au menu
platsResistance.append((typeDePlats[1],'plats résistance N-'+str(i),
prixDesPlats[1][ind]))
print(platsResistance)
for i in range(15):
ind=randrange(len(prixDesPlats[2]))
# l'on obtient un indices nous permettant d'attribuer
un prix aux hazard au menu
platsDessert.append((typeDePlats[2],'Dessert N-'+str(i),
prixDesPlats[2][ind]))
print(platsDessert)
#sauvegarde des plats
dans un fichier avec pickle
with open('liste_des_menus','wb') as file :
pickle.dump(platsEntree, file)
pickle.dump(platsResistance,
file)
pickle.dump(platsDessert,
file)
deuxieme
code : creation de la classe qui contient un menu en particulier
plats.py
""" dans
ce fichier nous allons creer nos différentes class et le fichier principal
"""
from tkinter import *
class platAffiche(LabelFrame): # la class
platAffiche herite de la class LabelFrame
def
__init__(self,boss,table,width,height,color="#55ff55"):
LabelFrame.__init__(self,height=int(height*0.15),labelanchor='nw',relief='ridge') # initialisation de la class LabelFrame
self.width,self.height,self.table,self.color=width,height,table,color #
initialisation des variable de l'init
self.titleLabel=Label(self,text=self.table[0],relief='ridge',
font=("verdana",10,"bold"),bg=self.color,fg="white")
# creation du label qui affichera le nom du labelframe
self.configure(labelwidget=self.titleLabel) # l'on fixe le label sur le
labelFrame
#creation des widgets de la class
self.canvas=Canvas(self,width=int(self.width*0.05),height=int(self.height*0.05),bg=self.color)
self.plat=Label(self,text='plat : '+self.table[1],relief='ridge',font=("verdana",8,"bold"),anchor='w')
self.prix=Label(self,text='prix : '+str(self.table[2])+'
fcfa',relief='ridge',font=("verdana",8,"bold"),anchor='w')
self.canvas.grid(column=0,row=0,rowspan=2,sticky='nswe',padx=5,pady=5)
self.plat.grid(column=1,row=0,sticky='nswe',padx=5,pady=5)
self.prix.grid(column=1,row=1,sticky='nswe',padx=5,pady=5)
if
__name__=="__main__": #permet de tester le fonctionement de la class
platClass=platAffiche(None,table=('entrée','okok et
eru',5000),width=800,height=560)
platClass.pack(expand=0,fill="both")
platClass.mainloop()
troisième
code : creation de la class qui affiche les menu d’un meme type et le
programme principal
code_restaurant.py
"""
creation de la page principal """
from tkinter import *
import plats # on importe notre fichier plats.py en tant que module pour
pouvoir acceder à la class platAffiche
import os, pickle
# creation des
variable pour recupere les sauvegarde du fichier contenant les menu
entree,resist,dessert=None,None,None
#recuperation
des menu avec pickle
with
open('liste_des_menus','rb') as file: # le fichier est ouvert en mode binaire
entree=pickle.load(file)
resist=pickle.load(file)
dessert=pickle.load(file)
# definition de
la class qui contiendra nos menu
class typeMenu(Frame):
def __init__(self,boss,height,width,title,table,color):
Frame.__init__(self,height=height,width=width,relief='groove',bd=5) #initialisation de la class Frame
self.height,self.width,self.title,self.table,self.color=height,width,title,table,color
self.posx,self.posy=int(self.width*0.27),int(self.height*0.1) # ces variables nous servirons à position les objets
windows du canvas
self.window,self.affiche=[],[]
#
creation des widgets de Frame
self.labTitle=Label(self,text=self.title,relief='ridge',font=("verdana",16,"bold"))
self.canvas=Canvas(self,width=int(self.width*0.8),height=int(self.height*0.20))
self.canvas.create_line(0,0,0,0,fill='black')
self.scroll=Scrollbar(self,orient="vertical",command=self.canvas.yview)
self.canvas.config(yscrollcommand=self.scroll.set)
self.labTitle.grid(column=0,row=0,columnspan=2,sticky="wnse")
self.scroll.grid(column=1,row=1,sticky="wns")
self.canvas.grid(column=0,row=1,sticky="nswe")
self.loader() # l'on active la fonction loader() en l'appelant
def loader(self):
"""cette fonction va
nous permettre de charger les differents menu sous forme d'objet de la class
platAffiche"""
for i in range(len(self.table)):
self.affiche.append(plats.platAffiche(self.canvas,self.table[i],self.width,self.height,self.color))
#on cree une instance de la class platAffiche depuis le module plats
que l'on a crée précedemment
if i%3==0:
self.window.append(self.canvas.create_window(int(self.posx/2),self.posy,window=self.affiche[i]))
#on cree un object window sur le canvas qui va nous permettre de
fixer notre class platAffiche sur le Canvas
elif i%3==1:
self.window.append(self.canvas.create_window(int(self.posx*2-self.posx/2),self.posy,window=self.affiche[i]))
#on cree un object window sur le canvas qui va nous permettre de
fixer notre class platAffiche sur le Canvas
else:
self.window.append(self.canvas.create_window(int(self.posx*3-self.posx/2),self.posy,window=self.affiche[i]))
#on
cree un object window sur le canvas qui va nous permettre de fixer notre class
platAffiche sur le Canvas
self.posy=self.posy+int(self.height*0.1) #pour chaque 3 objets fixer sur
le canvas, l'on va à la ligne
self.canvas.config(scrollregion=self.canvas.bbox('all')) # l'on
reconfigure le scrollbar pour qui puisse permettre de voir tout
# le contenu du canvas
"""programme
principal"""
fenetre=Tk()
fenetre.title('menu du
restaurant')
longueur,largeur=fenetre.winfo_screenwidth(),fenetre.winfo_screenheight()
fenetre.geometry=(str(longueur)+'x'+str(largeur)+'+0+0')
label=Label(fenetre, text
="bonjour à tous, nous vous \n souhaitons un \n excellent passage \ndans
notre restaurant. \n Nous vous souhaitons \nbonne appetit",
anchor="n",font=("verdana",12,"italic"),relief='groove',bd=5,justify='left')
#création des
instance de la class typeMenu pour nos différents type de menu
menuEntree=typeMenu(fenetre,largeur,longueur,"liste
des plats d'entrée",entree,'light blue')
menuResist=typeMenu(fenetre,largeur,longueur,"liste
des plats de résistance",resist,'light green')
menuDessert=typeMenu(fenetre,largeur,longueur,"liste
des plats des dessert",dessert,'#aa22ff')
piedDePage=Label(fenetre,
text ="bonne appetit à tous!",anchor="n",font=("verdana",45,"bold",'italic'),relief='groove',bd=5,justify='left')
label.grid(row=0,column=1,rowspan=3,sticky='nswe',pady=5)
menuEntree.grid(row=0,column=0,sticky='nswe',pady=5)
menuResist.grid(row=1,column=0,sticky='nswe',pady=5)
menuDessert.grid(row=2,column=0,sticky='nswe',pady=5)
piedDePage.grid(row=3,column=0,columnspan=2,sticky='nswe',pady=5)
fenetre.mainloop()
Commentaires