Accéder à un objet d'une classe - TKINTER

dammex Messages postés 31 Date d'inscription jeudi 22 juillet 2010 Statut Membre Dernière intervention 14 février 2017 - Modifié par dammex le 20/08/2013 à 14:30
lespinx Messages postés 106 Date d'inscription lundi 9 octobre 2006 Statut Membre Dernière intervention 23 novembre 2022 - 6 sept. 2013 à 17:05
Bonjour,

Je souhaite accéder depuis ma fonction VerificationServices à un objet de ma classe FenetreGraphique mais je ne trouve pas le moyen d'y parvenir.

Ci-dessous mon code simplifié :

from Tkinter import *
import time
from threading import Thread
import ttk

def VerificationServices():
# JE SOUHAITE ICI CHANGER LA COULEUR DU TEXTE DU LABEL LABEL1
# La commande ci-dessous ne fonctionne pas...
FenetreGraphique().Composants().Label1.config(fg="green")


class MonThread(Thread):
def __init__(self):
Thread.__init__(self)

def run(self):
VerificationServices()

def stop(self):
self.destroy()

class FenetreGraphique(Tk):
# CONSTRUCTEUR
def __init__(self):
Tk.__init__(self)
# Construction de la fenêtre graphique
self.ProprieteFenetre()
self.Composants()

# Propriétés de la fenêtre
def ProprieteFenetre(self):
# TITRE
self.title("Ma fenêtre graphique")

# Ajout des composants
def Composants(self):
# LABELS
Label1 = Label(self, text="Mon label !", fg="grey", font="Helvetica 11 bold")
Label1.pack()

# Démarrage du Thread
MonThread().start()


if __name__=='__main__':
Application=FenetreGraphique()
Application.mainloop()


Quelques explications au cas où...
- Je crée ma fenêtre graphique via la classe FenetreGraphique et je démarre un Thread en parrallèle car j'ai besoin d'effectuer certaines modifications elles aussi en parrallèle.
- Dans cet extrait de code, je souhaite simplement changer la couleur de mon Label1 en vert.

Merci beaucoup pour votre aide.

6 réponses

lespinx Messages postés 106 Date d'inscription lundi 9 octobre 2006 Statut Membre Dernière intervention 23 novembre 2022 77
22 août 2013 à 11:32
Bonjour,

Peut-être avez-vous déjà résolu votre Problème?

Sinon voici une piste.
1-Il vaut mieux lancer le thread après avoir instancié la classe car le lancement essaie de modifier l'attribut d'une classe qui n'a pas été instancié.

2-Pour modifier l'attribut d'une classe il vaut mieux utiliser une méthode de classe (Modif_Composants) et l'appeler depuis VerificationServices().

3-Pour présenter votre code il faut l'insérer entre les balises de l'icône Code

# -*- coding: ISO-8859-15 -*-
from Tkinter import *
import time
from threading import Thread
import ttk
def VerificationServices():
# JE SOUHAITE ICI CHANGER LA COULEUR DU TEXTE DU LABEL LABEL1
    Application.Modif_Composants()

class MonThread(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        VerificationServices()

    def stop(self):
        self.destroy(self)

class FenetreGraphique(Tk):
    # CONSTRUCTEUR
    def __init__(self):
        Tk.__init__(self)
        # Construction de la fenêtre graphique
        self.ProprieteFenetre()
        self.Composants()

    # Propriétés de la fenêtre
    def ProprieteFenetre(self):
        # TITRE
        self.title("Ma fenêtre graphique")

    # Ajout des composants
    def Composants(self):
        # LABELS
        self.Label1 = Label(self, text="Mon label !", fg="grey", font="Helvetica 11 bold")
        self.Label1.pack()

    def Modif_Composants(self):
        self.Label1.config(fg="green")

# Démarrage du Thread
#MonThread().start()

if __name__=='__main__':
    Application=FenetreGraphique()
    MonThread().start()
    Application.mainloop()


Cordialement.
1
dammex Messages postés 31 Date d'inscription jeudi 22 juillet 2010 Statut Membre Dernière intervention 14 février 2017 1
1 sept. 2013 à 16:39
Bonjour lespinx,

Désolé pour le retard... j'ai dû m'attarder sur autre chose...

Alors j'ai pris note de tes conseils et en effet çà fonctionne beaucoup mieux... Je reste cependant sur deux petits bugs :

- Je ne parviens pas à arrêter le Thread lorsque VerificationServices() est terminé (sortie de ma boucle while)
- Afficher le pourcentage de ma barre de progression. J'ai bien tenté d'utiliser l'attribut "variable" mais je tourne en rond.

Je te joins mon code actuel. Je pense que tu n'apprécieras pas l'ajout de labels vides pour sauter des lignes...

#!/usr/bin/env python
# -*- coding:Utf-8 -*-

#-------------------------------------------#
#          Importation des packages         #
#-------------------------------------------#
import Tkinter
from Tkinter import *
from threading import Thread
import ttk
import time
import os


#-------------------------------------------#
#         Declaration des variables         #
#-------------------------------------------#
arret_apache = 0
arret_tomcat = 0
arret_ndoutils = 0
arret_nagios = 0
arret_npcd = 0
demarrage_apache = 0
demarrage_tomcat = 0
demarrage_ndoutils = 0
demarrage_nagios = 0
demarrage_npcd = 0
phase_demarrage = 0
i = 0


#---------------------------------------------#
#  Declaration des fonctions d'incrementation #
#---------------------------------------------#
def mon_incrementation():
	global i 
	i = i+1
	
def ma_phase_de_demarrage():
	global phase_demarrage
	phase_demarrage = phase_demarrage + 1

def mon_incrementation_demarrage_apache():
	global demarrage_apache
	demarrage_apache = demarrage_apache + 1

def mon_incrementation_demarrage_tomcat():
	global demarrage_tomcat
	demarrage_tomcat = demarrage_tomcat + 1

def mon_incrementation_demarrage_ndoutils():
	global demarrage_ndoutils
	demarrage_ndoutils = demarrage_ndoutils + 1

def mon_incrementation_demarrage_nagios():
	global demarrage_nagios
	demarrage_nagios = demarrage_nagios + 1

def mon_incrementation_demarrage_npcd():
	global demarrage_npcd
	demarrage_npcd = demarrage_npcd + 1

def mon_incrementation_arret_apache():
	global arret_apache
	arret_apache = arret_apache + 1

def mon_incrementation_arret_tomcat():
	global arret_tomcat
	arret_tomcat = arret_tomcat + 1

def mon_incrementation_arret_ndoutils():
	global arret_ndoutils
	arret_ndoutils = arret_ndoutils + 1

def mon_incrementation_arret_nagios():
	global arret_nagios
	arret_nagios = arret_nagios + 1

def mon_incrementation_arret_npcd():
	global arret_npcd
	arret_npcd = arret_npcd + 1

	
#-------------------------------------------#
#       Declararation des fonctions         #
#-------------------------------------------#
def VerificationServices():

	# Démarrage des vérifications d'arrêt et de remontée des services de supervision
	#logger -t redundancy -p local0.info "POPUP : Lancement de la fenêtre graphique"

	# Ne sors pas de la boucle tant que les processus n'ont pas été redémarrés
	Boucle = True
	while Boucle == True:

		# Phase 1 : Arrêt des services
		if phase_demarrage == 0:
		
			# Raffraichissement de la fenètre graphique toutes les secondes
			time.sleep(1)

			apache = os.popen("pgrep apache")
			apache = apache.read()
			if apache == "" and arret_apache == 0:
				mon_incrementation_arret_apache()
				Application.Modif_Composants("apache_KO")
				Application.UpdateBarreProgression()

			tomcat = os.popen("pgrep java")
			tomcat = tomcat.read()
			if tomcat == "" and arret_tomcat == 0:
				mon_incrementation_arret_tomcat()
				Application.Modif_Composants("tomcat_KO")
				Application.UpdateBarreProgression()

			ndoutils = os.popen("pgrep ndo2")
			ndoutils = ndoutils.read()
			if ndoutils == "" and arret_ndoutils == 0:
				mon_incrementation_arret_ndoutils() 
				Application.Modif_Composants("ndoutils_KO")
				Application.UpdateBarreProgression()

			nagios = os.popen("pgrep nagios")
			nagios = nagios.read()
			if nagios == "" and arret_nagios == 0:
				mon_incrementation_arret_nagios()
				Application.Modif_Composants("nagios_KO")
				Application.UpdateBarreProgression()

			npcd = os.popen("pgrep npcd")
			npcd = npcd.read()
			if npcd == "" and arret_npcd == 0:
				mon_incrementation_arret_npcd()
				Application.Modif_Composants("npcd_KO")
				Application.UpdateBarreProgression()

			if (apache == "") and (tomcat == "") \
			and (ndoutils == "") and (nagios == "") \
			and (npcd == ""):
				ma_phase_de_demarrage()
				Application.Modif_Composants("services_arrêtés")
				Boucle=False


class MonThread(Thread):
	def __init__(self):
		Thread.__init__(self)

	def run(self):
		# Vérification des services
		VerificationServices()
		time.sleep(3)
		
		# Fermeture automatique de la fenêtre graphique et de son thread
		#logger -t redundancy -p local0.info "POPUP : Fermeture du POPUP"
		Application.quit()
		self.stop()

	def stop(self):
		self.destroy(self)


class FenetreGraphique(Tk):
	# CONSTRUCTEUR
	def __init__(self):
		# Construction de la fenêtre graphique
		Tk.__init__(self)
		self.ProprieteFenetre()
		self.Composants()

	# Propriétés de la fenêtre
	def ProprieteFenetre(self):
	# TITRE
		self.title("Incident sur le serveur AUG-SRV-NP-2...")
		# Définition de la largeur et hauteur de la fenêtre graphique
		largeur = 400
		hauteur = 310
		# Calcul des coordonnées de centrage de la fenêtre graphique
		self.update_idletasks()
		x = (self.winfo_screenwidth() / 2) - (largeur / 2)
		y = (self.winfo_screenheight() / 2) - (hauteur / 2)
		# Positionnement de la fenêtre graphique
		self.geometry('{0}x{1}+{2}+{3}'.format(largeur, hauteur, x, y))
		# Désactivation de la fermeture et du redimensionnement
		#fenetre.protocol('WM_DELETE_WINDOW', lambda: None)
		self.resizable(0,0)

	# Ajout des composants
	def Composants(self):
		# LABELS
		self.LigneVide = Label(self,text="")
		self.LigneVide.pack()
		
		self.Message1 = Label(self,text="Pour des raisons techniques, le redémarrage",fg="red",font="Helvetica 12 bold italic")
		self.Message1.pack()
		self.Message2 = Label(self,text="des services de la supervision est necéssaire",fg="red",font="Helvetica 12 bold italic")
		self.Message2.pack()
		
		self.LigneVide = Label(self,text="")
		self.LigneVide.pack()
		
		self.Phase = Label(self,text="Phase d'arrêt des services",fg="orange",font="Helvetica 12 bold italic")
		self.Phase.pack()
		
		self.LigneVide = Label(self,text="")
		self.LigneVide.pack()
		
		self.Apache = Label(self,text="Arrêt du service APACHE en cours...",fg="black",font="Helvetica 11 bold")
		self.Apache.pack()
		self.Tomcat = Label(self,text="Arrêt du service TOMCAT en cours...",fg="black",font="Helvetica 11 bold")
		self.Tomcat.pack()
		self.Ndoutils = Label(self,text="Arrêt du service NDOUTILS en cours...",fg="black",font="Helvetica 11 bold")
		self.Ndoutils.pack()
		self.Nagios = Label(self,text="Arrêt du service NAGIOS en cours...",fg="black",font="Helvetica 11 bold")
		self.Nagios.pack()
		self.Ncpd = Label(self,text="Arrêt du Service NCPD en cours...",fg="black",font="Helvetica 11 bold")
		self.Ncpd.pack()
		
		self.LigneVide = Label(self,text="")
		self.LigneVide.pack()

		# Création de la barre de progression
		self.BarreProgression = ttk.Progressbar(self, length=350, mode='determinate')
		self.BarreProgression.pack()

	def Modif_Composants(self, message):
		# Logs et modifications des labels
		#if message == "services_arrêtés":
			#logger -t redundancy -p local0.info "POPUP : Phase d'arrêt des services OK"
		#if message == "services_redemarrés":
			#logger -t redundancy -p local0.info "POPUP : Phase de redémarrage des services OK"

		if message == "apache_KO":
			self.Apache.config(text="Service Apache arrêté",fg="grey")
			#logger -t redundancy -p local0.info "POPUP : Service APACHE arrêté"
		if message == "tomcat_KO":
			self.Tomcat.config(text="Service Tomcat arrêté",fg="grey")
			#logger -t redundancy -p local0.info "POPUP : Service TOMCAT arrêté"
		if message == "ndoutils_KO":
			self.Ndoutils.config(text="Service Ndoutils arrêté",fg="grey")
			#logger -t redundancy -p local0.info "POPUP : Service NDOUTILS arrêté"
		if message == "nagios_KO":
			self.Nagios.config(text="Service Nagios arrêté",fg="grey")
			#logger -t redundancy -p local0.info "POPUP : Service NAGIOS arrêté"
		if message == "npcd_KO":
			self.Ncpd.config(text="Service NPCD arrêté",fg="grey")
			#logger -t redundancy -p local0.info "POPUP : Service NCPD arrêté"


	def UpdateBarreProgression(self):
		self.BarreProgression.step(10)
	
	def quit(self):
		self.destroy()


#-------------------------------------------#
#                  MAIN                     #
#-------------------------------------------#
if __name__ == "__main__":
	Application=FenetreGraphique()
	MonThread().start()
	Application.mainloop()
0
lespinx Messages postés 106 Date d'inscription lundi 9 octobre 2006 Statut Membre Dernière intervention 23 novembre 2022 77
1 sept. 2013 à 22:02
Bonjour,

1- Pour eviter le remplissage par des label "ligne vide" il est conseillé d'utiliser les séquences d'échappement :
\r Carriage Return
\n Line Feed
\t Tabulation

Exemple:
self.Message1 = Label(self,text="\nPour des raisons techniques, le redémarrage\n des services de la supervision est necéssaire\n",fg="red",font="Helvetica 12 bold italic")
self.Apache = Label(self,text="Arrêt du service APACHE en cours...\n",fg="black",font="Helvetica 11 bold")

2- Control Variable voir ici => http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/control-variables.html
un exemple:
#Création label "Barre d'état"
self.var_lbl_Etat = StringVar()
#Initialisation ou modification
self.var_lbl_Etat.set("Répertoire en cours <" + self.rep_dossier + ">")

lbl_Etat = Label(self.frame_80, font = self.police, textvariable=self.var_lbl_Etat, width = 66, relief = "sunken")
lbl_Etat.pack()

#Lecture
self.etat = self.var_lbl_Etat.get()

3- Sur mon écran, la barre de progression n'apparait pas parce que la hauteur de la fenëtre graphique est unsuffisante (hauteur = 480 devrait suffire)

4- Arret thread
Voir un exemple ici = > http://www.commentcamarche.net/forum/affich-9006705-python-stopper-une-fonction

5- Saine lecture
Tkinter 8.5 en anglais http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html
Tkinter 8.4 en français http://ftp-developpez.com/michel-aubry/temp/tutoriels/python/tkinter-8-4-reference-interface-utilisateur-graphique-gui-pour-python/tkinter.pdf
0
dammex Messages postés 31 Date d'inscription jeudi 22 juillet 2010 Statut Membre Dernière intervention 14 février 2017 1
2 sept. 2013 à 20:47
OK.

Merci pour toutes ces infos.

Je jette un coup d'oeil sur toutes ces infos et je te ferai un retour.

Merci encore pour ton aide.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dammex Messages postés 31 Date d'inscription jeudi 22 juillet 2010 Statut Membre Dernière intervention 14 février 2017 1
6 sept. 2013 à 00:38
Bonsoir lespinx,

Je reviens vers toi concernant mon problème d'arrêt du Thread. J'ai bien lu toutes tes docs mais je ne parviens pas à éteindre mon Thread excepté par "Ctrl+Z"...

Je te joins le code principal:

#!/usr/bin/env python
# -*- coding:Utf-8 -*-

import Tkinter
from Tkinter import *
from threading import Thread
import ttk
import time
import os

def VerificationServices():
 *** Je vérifie tous mes services ***
*** Si tout est OK, appel de la fonction =>
        Application.Services_Redemarres()

class MonThread(Thread):
	def __init__(self):
		Thread.__init__(self)
		self.Boucle = True

	def run(self):
		# Démarrage des vérifications d'arrêt et de remontée des services de supervision
		#logger -t redundancy -p local0.info "POPUP : Lancement de la fenêtre graphique"
		while self.Boucle:
			VerificationServices()

	def stop(self):
		print "Arrêt du Thread"
		self.Boucle = False

class FenetreGraphique(Tk):
	# CONSTRUCTEUR
	def __init__(self):
		# Construction de la fenêtre graphique
		Tk.__init__(self)
		self.ProprieteFenetre() ### Centre ma fenêtre à l'écran
		self.Composants() ### Ajoute tous mes composants
		self.MonThread = MonThread()
		self.MonThread.start()

        def Services_Redemarres(self):
		self.quit()
		print "Appel de la fermeture du Thread"
		self.MonThread.stop()

	def quit(self):
		time.sleep(3)
		self.destroy()

if __name__ == "__main__":
	Application=FenetreGraphique()
	Application.mainloop()



Concernant toutes mes autres questions, j'ai pu les résoudre via lecture de tes docs :)

Merci beaucoup.
0
lespinx Messages postés 106 Date d'inscription lundi 9 octobre 2006 Statut Membre Dernière intervention 23 novembre 2022 77
6 sept. 2013 à 17:05
Bonjour,

Je pense que le thread s'arrête correctement.
Si vous souhaitez arrêter l'interface Tkinter après l'arrêt du thread voici une proposition:
if __name__ == "__main__":
	Application=FenetreGraphique()
	MyThread = MonThread()
	MyThread.start()
	MyThread.stop()
	Application.update_idletasks() #Force le rafraichissement de l"écran
	print "Arrêt application"
	time.sleep(3)
	Application.destroy()

	Application.mainloop()
0
Rejoignez-nous