IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Probleme de thread /IHM


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Par défaut Probleme de thread /IHM
    Bonjour à tous,

    Je travaille actuellement sur un petit scanner 3D. Pour concilier l'IHM avec la tache de fond de scan, j'utilise "threading". Je créé un thread, le lance, et communique avec lui par un flag event afin de lui dire s'il doit finir prematurement sa tache. Cela correspond au cas ou l'utilisateur demande d'annuler le scan en cours de route.

    Mon probleme se situe au niveau du bouton "scan on/off". En effet, tout fonctionne correctement, thread, flag, ...

    Par contre, lorsque j'arrete le thread (OFF), l'IHM reagit comme si je venait de cliquer sur ON. Et ça repart, et cette fois je perd la main. Une idée?

    Ci dessous les code des fonctions en cause. Elle font parties de deux classes differentes. AU beosin, je peut poster l'ensemble des deux fichiers, voir le projet.

    Merci d'avance pour votre aide.

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    def p_scan(self, config_dict, event):
    		"""
                            Allow to know the execution path
                            
                            PARAMETERS
                            ==========
                                    None    
                                                    
                            RETURNS
                            =======
                                    The execution path
                    """
    		#Init of variables
    		pourcentage = 0
    		pas = 0
     
     
    		self.config_dict = config_dict
     
     
    		#Init of path
    		path_file_ouput = os.path.join(self.path_base, self.config_dict["FILE_DST_DIR"])
    		path_file_ouput = os.path.join(path_file_ouput, self.interface.p_choice_file_name())
     
    		path_snapshot1 = os.path.join(self.path_base, self.config_dict["FILE_TMP_DIR"])
    		path_snapshot1 = os.path.join(path_snapshot1, "Capture1.png")
     
    		path_webcam1 = path2 = os.path.join(self.path_base, self.config_dict["FILE_TMP_DIR"])
    		path_webcam1 = os.path.join(path_webcam1, "Webcam1.png")
     
    		path_snapshot2 = os.path.join(self.path_base, self.config_dict["FILE_TMP_DIR"])
    		path_snapshot2 = os.path.join(path_snapshot2, "Capture2.png")
     
    		path_webcam2 = path2 = os.path.join(self.path_base, self.config_dict["FILE_TMP_DIR"])
    		path_webcam2 = os.path.join(path_webcam2, "Webcam2.png")
     
    		path_mire = path2 = os.path.join(self.path_base, "02-IMG/Mire.png")
     
     
    		cur_vh, cur_vl, cur_hh, cur_hl = self.interface.f_cursor_get_position()
     
     
    		self.webcam = self.f_init_webcam()
    		self.webcam.p_open_flux(int(self.config_dict["WEBCAM_NUMBER"]))
     
     
    		if self.interface.p_choice_ext() == "xyz":
    			self.fileoutput = self.f_init_fileout_xyz()
    		elif self.interface.p_choice_ext() == "obj":
    			self.fileoutput = self.f_init_fileout_obj()
    		else:
    			self.interface.p_gtk_win_error(None, self.dict_error["ERR006"])
     
     
    		self.fileoutput.p_file_open(path_file_ouput)
    		self.fileoutput.f_file_write_entete(self.interface.p_choice_file_name())
     
     
    		motor_angle = 0.0 #nb pas * angle pas * mode
     
     
    		start = time.time()
     
     
    		while(( motor_angle) < 15 and not (event.isSet())):
    			print "event:", event.isSet()
    			try:
    				rtr0 = self.serialcom.f_emet_text(self.dict_arduino["LIGHT_OFF"])
    				rtr1 = self.serialcom.f_emet_text(self.dict_arduino["LASER_OFF"])
    				rtr2 = self.serialcom.f_emet_text(self.dict_arduino["LASER1_ON"])
    			except:
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
     
    			door = self.p_ihm_upd(pas)
    			if door == "false":
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
    				break
     
    			#self.webcam.p_capture_frame1(path_snapshot1, float(self.config_dict["WEBCAM_SENSIBILITY"]))
     
    			self.img.p_webcam_capture1(path_snapshot1, path_webcam1, cur_vh, cur_vl, cur_hh, cur_hl)
     
    			door = self.p_ihm_upd(pas)
    			if door == "false":
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
    				break
     
    			self.interface.p_webcam_upd_img(path_webcam1)
     
    			try:
    				rtr1 = self.serialcom.f_emet_text(self.dict_arduino["LASER_OFF"])
    				rtr2 = self.serialcom.f_emet_text(self.dict_arduino["LASER2_ON"])
    			except:
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
     
    			door = self.p_ihm_upd(pas)
    			if door == "false":
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
    				break
     
    			#self.webcam.p_capture_frame2(path_snapshot2, float(self.config_dict["WEBCAM_SENSIBILITY"]))
     
    			self.img.p_webcam_capture1(path_snapshot2, path_webcam2, cur_vh, cur_vl, cur_hh, cur_hl)
     
    			door = self.p_ihm_upd(pas)
    			if door == "false":
    				elf.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
    				break
     
     
    			self.interface.p_webcam_upd_img(path_webcam2)
     
     
    			#Compute img 1 & 2
    			angle = motor_angle
    			angle2 = motor_angle + (180 - (2 * int(self.config_dict["LASER_ANGLE"])))
     
    			#tab_xyz = self.img.f_compute_img_left(path_snapshot1, cur_hh, cur_hl, cur_vh, cur_vl, angle)
    			#self.fileoutput.f_file_write_body(tab_xyz)
     
    			tab_xyz = self.img.f_compute_img_right(path_snapshot2, cur_hh, cur_hl, cur_vh, cur_vl, angle2)
    			self.fileoutput.f_file_write_body(tab_xyz)
     
    			try:
    				rtr0 = self.serialcom.f_emet_text(self.dict_arduino["MPAP+1"])
    			except:
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
     
    			motor_angle = motor_angle + ((360./int(self.config_dict["MPAP_NB_STEP"])) * int(self.config_dict["MPAP_MODE"]))
    			pas += 1
     
    			door = self.p_ihm_upd(pas)
    			if door == "false":
    				self.interface.p_gtk_win_error(None, self.dict_error["ERR002"])
    				break
     
    			pourcentage = (pas * 100) / int(self.config_dict["MPAP_NB_STEP"])
    			self.interface.p_pbar_upd_pourcentage(pourcentage)
     
    		print "event:", event.isSet()
    		print "event: effacement"
    		event.clear()
    		print "event:", event.isSet()
    		self.fileoutput.f_file_write_end()
    		self.fileoutput.p_file_close()
     
    		del self.webcam
    		del self.fileoutput
     
    		self.p_ihm_upd(pas)
     
    		stop = time.time()
     
    		self.interface.p_scan_end()
     
    		self.interface.p_webcam_upd_img(path_mire)
     
    		elapsed_time = stop-start
    		minute = int(elapsed_time/ 60)
    		seconde = int(elapsed_time - (minute * 60))
    		text = self.dict_info["INF002"] + "%s mn %s s"%(minute,seconde)
    		self.interface.p_gtk_win_info_thread(None,text)
    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    def p_button_clicked_scan(self, widget):
    		"""
                            Exit from software
                                    
                            PARAMETERS
                            ==========
                                    widget
                                    ------
                                            The widget that call the procedure
     
                            RETURNS
                            =======
                                    None
                    """
    		if self.scan3d_state is False:
    			self.p_sensitive_connect(False)
    			self.p_sensitive_file(False)
    			self.p_sensitive_param(False)
    			self.p_sensitive_cursors(False)
     
    			path_im_scann3d = os.path.join(self.path,"02-IMG/Stop.png")
    			self.scr_scan_im_button_scann3d.set_from_file(path_im_scann3d)
     
    			self.scr_scan_label_scann3d.set_label(self.dict_ihm["SCAN"]["SCAN_ON"])
     
    			self.scan3d_state = True
     
    			self.event_thread = threading.Event()
    			self.event_thread.clear()
     
     
    			print "test"
    			#self.tmp = thread.start_new_thread(self.fct_p_scan, (self.dict_config,))
    			self.tmp = threading.Thread(None, self.fct_p_scan, "scan", (self.dict_config, self.event_thread))
    			self.tmp.start()
     
     
    		else:
    			self.p_sensitive_connect(True)
    			self.p_sensitive_scan3d(True)
    			self.p_sensitive_file(True)
    			self.p_sensitive_param(True)
    			self.p_sensitive_cursors(True)
     
    			self.tmp._Thread__stop()
    			self.event_thread.set()
     
    			while self.event_thread.isSet():
    				time.sleep(0.25)
     
    			path_im_scann3d = os.path.join(self.path,"02-IMG/Start.png")
    			self.scr_scan_im_button_scann3d.set_from_file(path_im_scann3d)
     
    			self.scr_scan_label_scann3d.set_label(self.dict_ihm["SCAN"]["SCAN_OFF"])
     
    			#forcer l'arret du thread de scan si tjs existant
     
    			self.calibrate_state = False
    			self.scan3d_state = False

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je n'ai pas vu assez de code pour le savoir mais: le thread touche-t-il directement la partie graphique de l'IHM? Si oui, il faut modifier le code car, apparamment, PyGtk n'est pas thread-safe (ou pas entièrement).

  3. #3
    Expert confirmé

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Par défaut
    Bonjour Tyrtamos, et merci de ta reponse

    Je joint le code complet si tu veux lire, mais normalement, non, le thread n'a aucun acces direct, je passe par des "gobject.idle_add(", conformement au recommandations de pygtk.

    Je pense avoir trouvé une solution de contournement, mais cela m'oblige a revoir le fonctionnement du soft, et surtout, ne me donnera pas d'explications. Je prefererais autant comprendre precisement ce qui se passe.

    Merci beaucoup pour ton aide, et bonnes fêtes à toi
    Fichiers attachés Fichiers attachés

  4. #4
    Expert confirmé

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Par défaut
    Probleme trouvé. Comme quoi faire une petite pause, aide les meninges. MEA MAXIMA CULPA

    Alors explications. A la fin de la fonction appelée dans le thread, je rappelais la fonction gérant le clique sur le bouton scan, pour changer son etat. Seulement, depuis que j'ai codé ça, j'ai un peu etoffé le code dans cette dernière fonction.

    Voilà. Merci beaucoup en tout cas d'avoir jeté un coup d'oeil.

    Bonne nouvelle année

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bravo! Comme je ne travaille pas avec PyGtk, je n'aurais pas pu t'être d'un grand secours, mais j'aurais tout de même appliqué le grand principe: "ne jamais perdre une occasion d'apprendre quelque chose"...

    Bonne fête et bonne année à toi aussi!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme de threads
    Par cryptorchild dans le forum Langage
    Réponses: 7
    Dernier message: 02/02/2006, 02h27
  2. Problème de threads avec pthread_create
    Par 180degrés dans le forum Linux
    Réponses: 6
    Dernier message: 19/12/2005, 12h07
  3. Probleme fermeture Thread
    Par Raton dans le forum MFC
    Réponses: 4
    Dernier message: 29/09/2005, 09h51
  4. [Kylix] Problème de thread
    Par moltov dans le forum EDI
    Réponses: 1
    Dernier message: 22/06/2005, 13h28
  5. probleme d'affichage IHM 'Parametre incorrect'
    Par GENERYS dans le forum C++Builder
    Réponses: 5
    Dernier message: 26/11/2004, 16h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo