Voila déja bonjour a tous , je suis nouveau.
mais je voudrait surtout savoir comment faire pour utilisé des variable qui sont définie dans une class dans une autre class. merci d'avance a vos réponse
Voila déja bonjour a tous , je suis nouveau.
mais je voudrait surtout savoir comment faire pour utilisé des variable qui sont définie dans une class dans une autre class. merci d'avance a vos réponse
Tu peux préciser ta question ? Un exemple de code ?
dsl je suis vraiment pas trés douer lol
alor voila je vais expliquer clairement ma demande.
je suis en train de faire un programme asser compliquer qui nécésite de couper ma fenetre principale en trois paneau grace a la fonctiopn PanedWindow
sa y a pas de problemme et j'ai décider de remplir mes panneau en utilisant une class pour chacun d'eux. mais le probleme c'est que , avec cette méthode, les boutton d'une class ne peuveup pas inter-agir avec des variables d'une autre class (comme pas exemple) :
dans ce code je demande au programme de changer le label boujour en bye. Normalement rien de plus simple.
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 from Tkinter import * class Interface(Frame): def __init__(self): Frame.__init__(self) self.label=Label(self, text="Bonjour", fg='red') self.label.pack() self.boutton_=boutton() self.boutton_.pack() self.pack() class boutton(Frame): def __init__(self): Frame.__init__(self) self.boutton=Button(self, text="Bye", command=self.bye) self.boutton.pack() def bye(self): self.label.configure(text="Bye", fg='blue') if __name__=='__main__': App=Interface() App.mainloop()
Merci d'avoir pris la peine d'avoir lut mon post.
PS : je suis nouveau dans le forum, pas en python
Une solution dans ton cas serait de garder une référence vers le widget parent. Le mieux est de le passer via le constructeur de bouton. Comme ça tu pourrais accéder au label de l'autre classe.
Mais ça viole complètement l'orienté objet, aussi peut-être devrais-tu trouver une autre manière de le faire. Tu pourrais ajouter une méthode à ta frame principale pour changer le label du bouton par exemple. Même si c'est encore loin de la meilleure solution.
En fait, j'avais penser a définir ma class plutot de cette façon
a tout hasard : class boutton(Frame, Interface):
sa change absolument rien au programme mais se n'empèche pas son lancement.
par contre je vais juste te demander si tu peut détailler ton premier paragraphe parce que j'ai pas tout compris.
Et je ne vais pas ajouter de méthode a ma Frame principale parce que justement, le but c'est de faire inter-agir les paneau entre eux . J'ai pas vraiment d'idée de comment faire autrement
Salut,
Il faut pour cela bien comprendre le fonctionnement des class et de leur methodes, ainsi que c'est qu'une instance :
Jusque là, pas de problème. Regardons quels sont sont variables auquelles on peut acceder suivant le contexte:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 #une classe class Foo(object): attribute1=0 def __init__(self): self.attribute2=0 #et une de ses instances affectées à "instnc" instnc=Foo()
l'argument self de __init__ (et autres méthodes d'une classe ) est nommé self par convention, et à juste titre puique cela désigne l'instance elle-même : sauf indication contraire, une instance passe comme premier argument à toutes ses méthode de façon transparente une reférence à elle-même... on saisi donc mieux le sens de l'instruction "self.attibute2=0" qui signifie en python, plus littéralement : ma variable (la variable de moi-même) attribute2 -si elle n'existe pas, la créer- vaut 0.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Foo.attribute1 # retourne 0 instnc.attribute1 #retourne 0 Foo.attribute2 #lève une exception, parceque attibute2 n'est crée que lors de la création d'une instance de Foo (__init__ n'étant executé qu'a ce moment): instnc.attribute2 #nous retourne 0, puisque instnc est une instance
si depuis l'exterieur de l'instance, on voulais affecter la valeur 5 à attribute2 de l'instance "instnc" de Foo, on écrirait "instnc.attribute2=5". Tu remarqueras que la façon d'appeler un attribut d'une instance depuis l'extérieur de cette dernière est là même que celle employée pour appeler un attribut défini au niveau de la classe (ici attribute1).
Les attribut de classes et ceux des instances possèdes quelque subtilités:
On peut observer que la définition d'attribut à l'intérieur d'une classe, mais hors d'une de ses méthodes, sont des attributs dont la classe est en quelque sorte le "propriétaire". On peut observer également que test.x nous retourne la valeur de Foo.x ; ça à l'air simple, mais voici un schéma de la classe Foo et de l'instance test (juste après la création de cette dernière) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class Foo(object): x=56 y=22 test=Foo() print test.x #affiche 56 Foo.x=128 print test.x #affiche 128
Un pointeur, ici, et en faisant très simple, est comme une redirection, ce qui veut dire concretement qu'ici "test.x" revient à taper "Foo.x", parce que test n'a pas d'attribut x mais il sait que sa classe en possède un, donc il retourne la valeur de ce dernier...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Foo | +-x = 56 | +-y = 22 test | +-[liste de pointeurs vers les attributs hérités de Foo]
Ce schéma devrait t'aider à mieux comprendre le comportement suivant :
Eh oui, en faisant "test.x=128" on dit : l'attribut x de test est égale à 128
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 class Foo(object): x=56 y=22 test=Foo() test.x=128 print test.x #affiche 128 print Foo.x #affiche 56 Foo.x=273 print test.x #affiche 128 print Foo.x #affiche 273
on à donc crée l'attribut x car il n'existait pas dans instnc. Il est donc tout à fait normal que Foo.x n'ait pas été modifié.
Maintenant que test.x à été crée, si l'on veut qu'a nouveau text.x pointe vers Foo.x, il suffit de supprimer l'attribut x de instnc :
Tout ceci j'éspère t'aideras à deviner comment accéder à un attribut d'un classe depuis une autre classe (et même plus si je me suis pas expliquer comme un pied...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #depuis l'interieur de l'instance delattr(self, 'x') #ou del self.x #ou depuis l'exterieur delattr(instnc, 'x') #ou del instnc.x
EDIT: arf, trop long à écrire... était-ce bien utile du coup ? Je ne pense pas
sorry
WAOUUUU !
Franchement, je suis inscrit aujourd'hui et j'été un peu septique mais la j'évoue avoir une réponse complette en trés peu de temps qui va je suposse énormément m'aider.
par contre je vais la relire aprés avoir manger par ce que la le cerveau chauffe un peu.
Merci a toi N.Tox ! tu est mon roi
[se passe la main dans les cheuveux] Je sais, je sais... [/se passe la main dans les cheuveux]
Plus sérieusement, quand j'utilise un framework (ici Tkinter), j'ai toujours utilisé la méthode conseillée par Antoine_935 à savoir : garder un référence vers les autres widgets. Ce qui veut dire en gros que je ne sais pas si ce que je t'ai montré fonctionne pour les framework, je suppose que oui, y'a pas de raison...
Mais le principe qu'Antoine à évoqué (si je l'ai bien compris) peut être illustré de la sorte :
J'ai toujours procédé avec ce concept quand j'utilise un framework, je ne saurait donc vraiment te conseillée l'une ou l'autre méthode... à comparer donc...
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 class One(object): def __init__(self,parent=None,child=None): self.parent=parent self.child=child self.x=56 class Two(object): def __init__(self,parent=None,child=None): self.parent=parent self.child=child self.y=108 a=One() b=Two(a) a.child=b c=One(b,a) b.child=c a.parent=c a.x=145 print b.parent.x #affiche 145 print a.child.y #affiche 108
ben ,deja pour commencer je vais esseyer avec ta methode et apres je vais dire si sa marche ou pas. mais je peut rien faire ce soir donc j te dit pour demain. merci encore
J'ai fait un erreur sur le schémas que je t'ai montré, c'est corrigé maintenant
Franchement merci a toi N.Tox j'ai résolu mon problème. Et grâce a toi !
j'ai utilisé le fait que j'utilise une instance de ma class Interface pour afficher ma fenetre qui est dans
Merci encore a toi
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 if __name__=='__main__': App=Interface() App.mainloop() j'ai utilisé l'instance App de cette façon la : class boutton(Frame, Interface): def __init__(self): Frame.__init__(self) self.boutton=Button(self, text="Bye", command=self.bye) self.boutton.pack() def bye(self): App.label.configure(text="COUCOU", fg='blue')
bon voila. j'ai un autre problème qui est toujours le même a vrai dire.
dans le programme que je veu faire, j'utilise trois panneaux il faut donc alors quatres class,
une pour la fenetre principale et trois autre pour les panneaux. le mieux est que je mette vrai code
voila, mais lorsque j'appuis sur le boutton rajouter, le message inerte qui devait devenir OK ne change pas et je n'est aucun message d'erreur qui apparait sur ma console.
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
40
41
42
43
44
45
46
47
48 #coding:utf-8 from Tkinter import * class CompletteInterface(Frame): def __init__(self): Frame.__init__(self) self.master.geometry("840x480") self.pane = PanedWindow() self.pane.pack(fill="both", expand=1) self.gauche = Interface_Gauche() self.pane.add(self.gauche, width=170) self.pane2 = PanedWindow(self.pane, orient=VERTICAL) self.pane.add(self.pane2) self.haut = Interface_Haut() self.pane2.add(self.haut, height=300) self.bas = Interface_Bas() self.pane2.add(self.bas) self.pack() class Interface_Gauche(Frame, CompletteInterface): def __init__(self): Frame.__init__(self) self.mess_use=Label(self, text="Inerte", fg='red') self.mess_use.place(x=0, y=60) class Interface_Haut(Frame, CompletteInterface): def __init__(self): Frame.__init__(self) self.boutton=Button(self, text="Rajouter", command=self.coucou) self.boutton.place(x=0, y=0) def coucou(self): AppGauche.mess_use.configure(text='OK') class Interface_Bas(Frame): pass if __name__=='__main__': Aplication = CompletteInterface() AppGauche = Interface_Gauche() AppHaut = Interface_Haut() AppBas = Interface_Bas()
si quelqu'un pourrait (m'aider ou même me montrer comment résoudre se problème (N.Tox)
je commence a être désespéré malgré les trés bonne réponse qui mon été donné
Je te conseille vivement d'aller jeter un oeuil à cette partie du tuto python
http://python.developpez.com/cours/T...Chapitre7#L7.2
Il faut aussi que tu saches que, à chaque fois que tu crées un object (donc un de tes panneaux), c'est un nouvel objet qui est crée. Il n'a aucun rapport avec les autres.
Autrement dit, tu crées 3 panels dans ton if main, mais tu en crées 3 autres dans ton interface.
Plusieurs solutions :
solution n°1 (et pas très élégante...):
j'ai utiliser "global AppGauche" dans Interface_Haut.coucou() parceque AppGauche est définie hors de la classe Interface_Haut, hors pour pouvoir acceder à des variables et des objets situés à l'extérieur d'une fonction ou d'une classe (ou d'une instance du même coup) on spécifie qu'une variable doit être recherchée à l'extérieur en mettant "global xxx". Il reste toutefois très conseillé de faire autrement tant qu'on le peut...
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
40
41
42
43
44
45
46
47
48
49 #coding:utf-8 from Tkinter import * class CompletteInterface(Frame): def __init__(self): Frame.__init__(self) self.master.geometry("840x480") self.pane = PanedWindow() self.pane.pack(fill="both", expand=1) self.gauche = Interface_Gauche() self.pane.add(self.gauche, width=170) self.pane2 = PanedWindow(self.pane, orient=VERTICAL) self.pane.add(self.pane2) self.haut = Interface_Haut() self.pane2.add(self.haut, height=300) self.bas = Interface_Bas() self.pane2.add(self.bas) self.pack() class Interface_Gauche(Frame, CompletteInterface): def __init__(self): Frame.__init__(self) self.mess_use=Label(self, text="Inerte", fg='red') self.mess_use.place(x=0, y=60) class Interface_Haut(Frame, CompletteInterface): def __init__(self): Frame.__init__(self) self.boutton=Button(self, text="Rajouter", command=self.coucou) self.boutton.place(x=0, y=0) def coucou(self): global AppGauche AppGauche.mess_use.configure(text='OK') class Interface_Bas(Frame): pass if __name__=='__main__': Aplication = CompletteInterface() AppGauche = Interface_Gauche() AppHaut = Interface_Haut() AppBas = Interface_Bas()
solution n°2 (un poil plus élégant, m'enfin bon...)
c'est l'application de la méthode qu'Antoine_935 suggérait au tout début, et qui reste à mon avis la plus fiable pour ce qui est (au moins) des framework.
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
40
41
42
43
44
45
46
47
48
49
50 #coding:utf-8 from Tkinter import * class CompletteInterface(Frame): def __init__(self): Frame.__init__(self) self.master.geometry("840x480") self.pane = PanedWindow() self.pane.pack(fill="both", expand=1) self.gauche = Interface_Gauche(self) self.pane.add(self.gauche, width=170) self.pane2 = PanedWindow(self.pane, orient=VERTICAL) self.pane.add(self.pane2) self.haut = Interface_Haut(self) self.pane2.add(self.haut, height=300) self.bas = Interface_Bas() self.pane2.add(self.bas) self.pack() class Interface_Gauche(Frame, CompletteInterface): def __init__(self,parent): Frame.__init__(self) self.parent=parent self.mess_use=Label(self, text="Inerte", fg='red') self.mess_use.place(x=0, y=60) class Interface_Haut(Frame, CompletteInterface): def __init__(self,parent): Frame.__init__(self) self.parent=parent self.boutton=Button(self, text="Rajouter", command=self.coucou) self.boutton.place(x=0, y=0) def coucou(self): self.parent.gauche.mess_use.configure(text='OK') class Interface_Bas(Frame): pass if __name__=='__main__': Aplication = CompletteInterface() AppGauche = Interface_Gauche() AppHaut = Interface_Haut() AppBas = Interface_Bas()
Toutefois je ne comprends pas pourquoi Interface_Gauche et Interface_Haut héritent de CompletteInterface (Complette qui soit dit en passant devrait sûrement s'écrire Complete )...
Entièrement d'accord En plus, le fait de passer le parent en paramètre reste bien dans l'esprit de tkinter.et qui reste à mon avis la plus fiable pour ce qui est (au moins) des framework
On peut accéder aux variables globales sans le global. La différence est que si tu essayes de réassigner ces variables, ça va créer une variable locale, sur laquelle l'assignation se fera.
On peut même avoir des bugs Si tu essaye d'accéder à une variable globale, puis qu'après seulement tu la redéfinis en local...
Bien sur, tu as aussi accès aux attributs de ces variables, et même sans le global donc, tu peux influer sur des objets. Tu peux, par exemple, faire un list.append, qui sera effectivement appelé.
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 >>> a = 42 >>> >>> def test1(): ... print(a) ... >>> test1() 42 >>> def test2(): ... a = 51 ... >>> test2() >>> a 42 >>> def test3(): ... global a ... a = 51 ... >>> test3() >>> a 51 >>> def test4(): ... print(a) ... a = 67 ... >>> test4() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in test4 UnboundLocalError: local variable 'a' referenced before assignment
Intéressant, mais bon seulement dans une optique de debug, cause ça me semble pas très propre d'exploiter cette propriété...
En même temps, c'est p'tête qu'une question d'habitude...
Dans tous les cas, quelque chose me chiffonne Rezus... Je comprend pas pourquoi tu crées des instances de Interface_(Gauche, Haut et Bas) depuis la bloc d'instruction de "if __name__=="__main__": " puisque des instances de ces classes sont crée depuis CompletteInterface.__init__() (Ceci dit je comprends un mieux alors, pourquoi ces classes héritent de CompletteInterface...) ?
merci a tous pour ces réponses.
j'ai finalement utilisé la méthode la plus élégante d'Antoine_935 et sa marche trés bien
le fait que Interface_Haut et Interface_Gauche hérite de CompletteInterface (qui s'écrit Complete je vais rectifier !)
c'était un simple test pour voir si mon problème ne pouvait pas se résoudre de cette façon. ainse que faire une instance dans le bloc d'instruction if __name__=='__main__':
la aussi c"était un test
En tout cas merci baucoup a vous
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager