Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/01/2015, à 16:12

totola

[Résolu]Tkinter canvas créer puis effacer une ligne

Bonjour,
avec un système de 2 cases à cocher et un bouton associé, je créé une ligne d'un point A à un point B lorsque je clique sur le bouton.
J'aimerais pouvoir l'effacer de la même manière... (lorsque les cases sont séléctionnées et en cliquant sur un autre bouton). Voilà à quoi ressemble mon code:

		canvas1 = Tkinter.Canvas(width = 110, height = 390)
		canvas1.place(x=278, y=253, anchor="c")

#retour1 et retour2 sont liés aux cases à cocher et TracerTrait() est la fonction appelé par le bouton 1

               def TracerTrait():
			if retour1.get() and retour2.get(): 
				a21 = canvas1.create_line(6,240,6,345, fill="green",arrow=BOTH)

#EffacerTrait() est la fonction appelée par le bouton 2

               def EffacerTrait():
			if retour1.get() and retour2.get(): 
				canvas1.delete(a21)

Alors, j'ai remarqué que si je "sors" la création de la ligne de la condition if (fonction du bouton 1) et que je la créé directement dans le programme, le bouton pour effacer fonctionne bien mais pas si je la créé comme je voudrais avec le bouton.

L'erreur est la suivante:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
    return self.func(*args)
  File "a.py", line 749, in DeconnecterPostes
    EffacerTrait()
  File "a.py", line 692, in EffacerTrait
    canvas1.delete(a21)
NameError: global name 'a21' is not defined

Merci de votre aide smile

Dernière modification par totola (Le 24/01/2015, à 21:14)

Hors ligne

#2 Le 24/01/2015, à 17:11

tiramiseb

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Salut,

Tu as défini une variable a21 locale à ta fonction TracerTrait. Du coup la fonction EffacerTrait n'y a pas accès.
Il faut que tu trouves une manière de conserver cette référence en dehors de la fonction si tu veux y accéder.
Tu peux éventuellement mettre une variable directement dans ton module Python, mais bon ça fait genre variable globale, c'est pas joli joli.

Ou alors avec Tkinter il y a une manière de récupérer la chose sans devoir réutiliser cette variable, mais je ne connais pas du tout Tkinter.

Enfin, je vois que les définitions de fonctions sont indentées, cela voudrait dire qu'elles sont dans quelque chose, par contre il n'y a pas l'argument "self" alors ce ne sont pas des méthodes d'une classe : qu'as-tu fait à ce niveau-là ?

Hors ligne

#3 Le 24/01/2015, à 19:25

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

tiramiseb a écrit :

Salut,

Tu as défini une variable a21 locale à ta fonction TracerTrait. Du coup la fonction EffacerTrait n'y a pas accès.
Il faut que tu trouves une manière de conserver cette référence en dehors de la fonction si tu veux y accéder.

D'accord, je comprends au moins en principe...

Tu peux éventuellement mettre une variable directement dans ton module Python, mais bon ça fait genre variable globale, c'est pas joli joli.

ça je ne sais pas faire? Mais même si c'est pas trop joli, je cherche juste à ce que ça marche... :°

Enfin, je vois que les définitions de fonctions sont indentées, cela voudrait dire qu'elles sont dans quelque chose, par contre il n'y a pas l'argument "self" alors ce ne sont pas des méthodes d'une classe : qu'as-tu fait à ce niveau-là ?

Alors voici le début et la fin de mon code:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import Tkinter,os,time
import tkFileDialog
from Tkinter import *
from tkFileDialog import askopenfilename
from fabric.api import *
 


class simpleapp_tk(Tkinter.Tk):
	def __init__(self,parent):
		Tkinter.Tk.__init__(self,parent)
		self.parent = parent
		self.initialize()

	def initialize(self):
		self.grid()

		self.entryVariable = Tkinter.StringVar()
		self.entry = Tkinter.Entry(self,textvariable=self.entryVariable)


#le bout de mon code:

                canvas1 = Tkinter.Canvas(width = 110, height = 390)
		canvas1.place(x=278, y=253, anchor="c")

		def TracerTrait():
			if retour1.get() and retour2.get(): 
				a21 = canvas1.create_line(6,240,6,345, fill="green",arrow=BOTH)

		def EffacerTrait():
			if retour1.get() and retour2.get(): 
				canvas1.delete(a21)

#Et la fin

                self.resizable(True,True)
		self.entry.focus_set()
		self.entry.selection_range(0, Tkinter.END)




if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.mainloop()

Voilà, Je débute en programmation et en python, alors je ne maîtrise pas tout encore :s
merci en tout cas pour l'aide! smile

Dernière modification par totola (Le 25/01/2015, à 20:46)

Hors ligne

#4 Le 24/01/2015, à 20:55

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Je crois que j'ai trouvé le coup de la variable  globale:

global a21

Et voilà... Mais pourquoi c'est pas joli joli..???

Hors ligne

#5 Le 25/01/2015, à 20:36

tiramiseb

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Et voilà... Mais pourquoi c'est pas joli joli..???

Lis simplement ça :
http://fr.wikipedia.org/wiki/Variable_g … 3.A9nients
smile

-----

Par ailleurs, je ne comprends toujours pas l'imbrication de tes deux fonctions : les lignes "def" ont une indentation tout à fait inhabituelle : 15 caractères, contre des tabulations pour tout le reste...

Hors ligne

#6 Le 25/01/2015, à 20:43

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Ah oui... c'est parfaitement clair... :s
Bon j'essaierai de m'en souvenir si ça pose problème pour la suite... smile
Pour les indentations, c'est juste une erreur de copier-coller je pense... Je corrige sur le post.

Sinon, autre chose, pas une petite idée concernant les threads?? Je galère trop là... :s

http://forum.ubuntu-fr.org/viewtopic.php?id=1770441

Dernière modification par totola (Le 25/01/2015, à 20:47)

Hors ligne

#7 Le 25/01/2015, à 20:50

tiramiseb

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Pour les indentations, c'est juste une erreur de copier-coller je pense...

Donc tu définis des fonctions au sein de ta méthode initialize ?

Mets plutôt TracerTrait et EffacerTrait (et tes éventuelles autre fonctions que tu ne nous as pas montré) comme méthodes de ta classe simpleapp_tk (avec donc un argument "self") et stocke ta variable a21 en tant que variable de classe, par "self.a21".


-----

Par ailleurs, pourquoi créer une méthode "initialize" alors que tu utilises déjà le "__init__" tout à fait standard ?

Dernière modification par tiramiseb (Le 25/01/2015, à 20:51)

Hors ligne

#8 Le 25/01/2015, à 20:54

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Ah ok, je vais regarder ça! ça paraît plus logique en effet. Merci!

Hors ligne

#9 Le 25/01/2015, à 20:58

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

tiramiseb a écrit :

Par ailleurs, pourquoi créer une méthode "initialize" alors que tu utilises déjà le "__init__" tout à fait standard ?

Ben parce que pour l'instant je copie-colle des trucs sans tout comprendre... :s
Mais grâce aux gentils forumeurs qui prennent de leur temps pour m'expliquer je progresse petit à petit wink
Merci beaucoup!

Hors ligne

#10 Le 25/01/2015, à 21:38

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Bon j'ai déjà remplacé toutes mes variables globales (j'en avais un paquet...) par des self.var dans toutes mes fonctions.
ça marche... Merci!

Hors ligne

#11 Le 25/01/2015, à 22:06

tiramiseb

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Pour le "initialize", c'est redondant vu que __init__ est déjà là pour initialiser la classe...

Hors ligne

#12 Le 25/01/2015, à 22:08

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Oui, j'ai également viré ça sans soucis:

self.initialize()
	def initialize(self):

Merci, je commence à y voir plus clair.

Dernière modification par totola (Le 25/01/2015, à 22:08)

Hors ligne

#13 Le 25/01/2015, à 22:11

totola

Re : [Résolu]Tkinter canvas créer puis effacer une ligne

Et sinon, pour mes histoires de threads? Pas de pistes?
J'ai cru voir que ce n'était pas simple avec Tkinter... Est-ce qu'il vaudrait mieux que je recode le tout avec pyGTK ou wxpython?? Il y a l'air d'y avoir plus d'exemples et de docs...

Hors ligne