Je travaille actuellement sur l'élaboration d'un outil qui servirait à faire l'appel dans une classe.
L'idée est la suivante :
Créer un tableau de n Lignes et m Colonnes. La première ligne serait rempli par Jour1, Jour 2, ...., Jour m et la première colonne par Nom1, Nom 2, ..., Nom n.
Les autres cases seraient des entrées avec un choix sous forme de liste déroulante (Présent, Absent) (combobox).
J'ai donc conçu le code suivant :
from tkinter import *
from tkinter import ttk
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def Selected_elem(event):
a=Saisie[i][j].get()
print(a)
return(a)
root = Tk()
root.title("Présence / abscence")
root.geometry("1080x720")
frm1 = Frame(root,bg="white",width=1000,height=1000)
frm1.pack()
frm1.rowconfigure(0,weight=1)
frm1.columnconfigure(0,weight=1)
Colonne = 10
Ligne = 5
Saisie = np.full((11,6)," ",dtype=object)
a=" "
for i in range (Colonne+1):
Label(frm1,text=" J%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=i,row=0)
for i in range (Ligne+1):
Label(frm1,text=" Eleve%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=0,row=i)
for i in range (1,Colonne+1):
for j in range (1, Ligne+1):
Saisie[i][j]=ttk.Combobox(frm1,values=["Absent","Présent"],width=5)
Saisie[i][j].grid(column=i,row=j)
Saisie[i][j].bind("<<ComboboxSelected>>", Selected_elem)
root.mainloop()
J'obtiens bien mon tableau :
Mais j'ai remarqué que seul la dernière case de celui-ci était prise en compte. Pouvez-vous m'aider ?
from tkinter import Button, Tk
class MyButton(Button):
buttons = []
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
MyButton.buttons.append(self)
self["text"] = f"Button-{len(MyButton.buttons)}"
def my_command():
print(f"Il y a {len(MyButton.buttons)} boutons")
root = Tk()
for _ in range(10):
button = MyButton(root, command=my_command)
button.pack()
print(MyButton.buttons)
root.mainloop()
- Edité par fred1599 4 août 2021 à 11:21:11
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
def Selected_elem(event,l,c):
a=Saisie[l][c].get()
print(a)
# et ensuite:
for i in range (0,Ligne):
for j in range (0, Colonne):
Saisie[i][j]=ttk.Combobox(fen,values=["Absent","Présent"],width=5)
Saisie[i][j].grid(column=j,row=i)
Saisie[i][j].bind("<<ComboboxSelected>>", lambda event, l=i, c=j: Selected_elem(event, l, c))
Pour Phil_1857 : En effet le problème vient bien du fait qu'il me renvoie le Saisie[10][5]. Mais je ne vois pas comment faire pour avoir les valeurs de chaque case.
Pour fred1599 : Je vais regarder plus en détail ce que tu as fait. J'ai testé tes programmes et j'essaye de les comprendre. Je n'ai pas encore appris l'utilisation des classes en Python. Je pense que c'est le bon moment pour se plonger dans un tuto ;).
Après faire quelque chose de propre et organisé sans classe c'est possible, suffit juste d'être clair dans sa tête.
Je partais sur le principe qu'on souhaite changer le comportement, et y ajouter une fonctionnalité de compteur sur les objets créés, mais d'autres solutions existent bien évidemment, peut-être moins techniques mais tout aussi efficaces.
- Edité par fred1599 4 août 2021 à 11:54:48
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Merci umfred pour ta réponse, je vais regarder ça.
En fait j'ai en partie trouver la solution :
from tkinter import *
from tkinter import ttk
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def Selected_elem(event):
for i in range (1,Colonne+1):
for j in range (1,Ligne+1):
Saisie[i][j]=Saisie[i][j].get()
print(Saisie)
return(Saisie)
root = Tk()
root.title("Présence / abscence")
root.geometry("1080x720")
frm1 = Frame(root,bg="white",width=1000,height=1000)
frm1.pack()
frm1.rowconfigure(0,weight=1)
frm1.columnconfigure(0,weight=1)
Colonne = 10
Ligne = 5
Saisie = np.full((11,6)," ", dtype = object)
a=" "
for i in range (Colonne+1):
Label(frm1,text=" J%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=i,row=0)
Saisie[i][0]=" J%s "%i
for i in range (Ligne+1):
Label(frm1,text=" Eleve%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=0,row=i)
Saisie[0][i]=" J%s "%i
for i in range (1,Colonne+1):
for j in range (1, Ligne+1):
Saisie[i][j]=StringVar()
Saisie[i][j]=ttk.Combobox(frm1,values=["Absent","Présent"],width=5)
Saisie[i][j].grid(column=i,row=j)
Saisie[i][j].bind("<<ComboboxSelected>>", Selected_elem)
root.mainloop()
J'ai rajouté une double boucle dans la fonction évènement.
Le problème c'est que le changement va fonctionner une fois. Ensuite, ce message d'erreur apparaît :
Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\py37_v1\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "T:/DE/Dmta/Travail/Exterieur/Stagiaires/DUCROCQ Thibaut/python/sanstitre0.py", line 18, in Selected_elem
Saisie[i][j]=Saisie[i][j].get()
AttributeError: 'str' object has no attribute 'get'
Je pense que cela doit venir du type de Saisie[i][j] mais je ne vois pas comment le corriger.
la ligne 41 est sans effet, puisqu'à cette ligne, tu dis que c'est une StringVar() et la ligne suivante, c'est un ComboBox
Et c'est parce que ligne 12, tu dis que Saisie[i][j] est un string (vu que tu lui affectes la valeur du Combobox) que la prochaine fois, tu ne peux pas l'interroger comme un Combobox et récupérer ensuite sa valeur. Il faut que soit tu ais un tableau des valeurs à côté (une autre variable), soit tu te demandes si tu as vraiment besoin de ce tableau et utiliser directement ton tableau d'objet
Pour Phil_1857 : En effet le problème vient bien du fait qu'il me renvoie le Saisie[10][5]. Mais je ne vois pas comment faire pour avoir les valeurs de chaque case.
Thibault, tu n'as pas bien lu ma réponse dans la quelle je proposais une solution qui marche
je te la redonne ici, et ca fonctionne parfaitement:
Excusez moi de revenir si tardivement sur ce sujet. Je n'ai pas eu trop le temps de travailler dessus ces 2 dernières semaines.
Merci beaucoup Phil pour la commande .bind. J'avais mal compris la notion de lambda event.
Maintenant que ça fonctionne, j'ai voulu aller un peu plus loin. Dans la première version de mon petit programme, la taille de mon tableau était fixée. Pour être plus libre, j'ai ajouté 2 entry (nombre de colonne et nombre de ligne) et un bouton qui génère le tableau une fois les données sont entrées.
J'aimerai aussi que une fois que le tableau est généré, je puisse modifier ces dimensions sans devoir fermer la fenêtre. Pour agrandir le tableau, il n'y a pas de problème. Pour le rétrécir, ça coince.
Mon code :
from tkinter import *
from tkinter import ttk
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def CreerTab1 ():
def Selected_elem(event,l,c):
a=Saisie[l][c].get()
tab1[l][c]=a
dataframe = pd.DataFrame(data=tab1)
print (tab1)
print(dataframe)
return(tab1)
frm2.delete('ALL')
Colonne = saisir_Colonne.get()
Ligne = saisir_Ligne.get()
tab1 = np.full((Ligne+1,Colonne+1)," ", dtype = object)
LabelFrame(frm2,text=" Eleve ",borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=0,row=0)
tab1[0][0]=" Eleve "
Saisie = np.full((Ligne+1,Colonne+1)," ", dtype = object)
a=" "
for i in range (1,Colonne+1):
Label(frm2,text=" J%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=i,row=0)
Saisie[0][i]=" J%s "%i
tab1[0][i] = "J%s "%i
for i in range (1,Ligne+1):
Label(frm2,text=" Eleve%s "%i,borderwidth=1,relief="solid",font=("Arial, 12"),bg="white").grid(column=0,row=i)
Saisie[i][0]=" Eleve%s "%i
tab1[i][0]="Eleve%s"%i
for i in range (1,Ligne+1):
for j in range (1, Colonne+1):
Saisie[i][j]=StringVar()
Saisie[i][j]=ttk.Combobox(frm2,values=["Absent","Présent"],width=5)
Saisie[i][j].grid(column=j,row=i)
Saisie[i][j].bind("<<ComboboxSelected>>", lambda event, l=i, c=j: Selected_elem(event, l, c))
root = Tk()
root.title("Présence / abscence")
root.geometry("1080x720")
frm1 = Frame(root,bg="white",width=1000,height=1000)
frm1.pack()
frm1.rowconfigure(0,weight=1)
frm1.columnconfigure(0,weight=1)
Label(frm1,text="Entrez le nombre de colonnes :",font=("Arial,12"),bg="white").grid(column=0,row=0)
saisir_Colonne = IntVar()
saisir_Colonne.set(0)
saisie_Colonne = Entry(frm1,textvariable=saisir_Colonne,width=5,justify = CENTER)
saisie_Colonne.grid(column=1,row=0)
Label(frm1,text="Entrez le nombre de lignes :",font=("Arial,12"),bg="white").grid(column=0,row=1)
saisir_Ligne = IntVar()
saisir_Ligne.set(0)
saisie_Ligne = Entry(frm1,textvariable=saisir_Ligne,width=5,justify = CENTER)
saisie_Ligne.grid(column=1,row=1)
frm2 = Canvas(root,bg="white",width=1000,height=1000)
frm2.pack()
frm2.rowconfigure(0,weight=1)
frm2.columnconfigure(0,weight=1)
PrintTab1 = Button(frm1,text="Générer Tableau",command=CreerTab1)
PrintTab1.grid(column=1,row=4)
root.mainloop()
Pour arriver à mes fins, j'ai vu sur des forums qu'on pouvait utiliser un canvas au lieu d'un frame et pour supprimer le contenu, utiliser la commande NomDuCanvas.delete("ALL") mais ça ne fonctionne pas.
Vous auriez une idée de comment faire ?
- Edité par ThibautDucrocq 18 août 2021 à 10:38:28
Tu peux passer le sujet à "résolu" (bouton en haut à droite du sujet) et cliquer sur les pouces levés des messages qui t'ont aidé⋅e
Remplir un tableau dans la fenêtre Tkinter
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)