[RESOLU] Fenetre qui ne se ferme pas depuis un Thread

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

[RESOLU] Fenetre qui ne se ferme pas depuis un Thread

Message par falsam »

Bonjour. Je n'arrive pas à fermer une fenêtre à l'issu d'une boucle dans un thread.
un exemple simplifié de mon code.

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
  #ProgressForm
  #Progress
EndEnumeration

Define WindowEvent

;Affichage de la boite de dialogue de progression
Procedure ShowProgress()
  OpenWindow(#ProgressForm, 0, 0, 200, 100, "", #PB_Window_ScreenCentered, WindowID(#Mainform))
  ProgressBarGadget(#Progress, 5, 40, 190, 20, 0, 100) 
EndProcedure

;Le thread
Procedure Count(Value)
  Protected i.i
  For i=1 To 1000
    SetGadgetState(#Progress, i/10)
  Next  

  CloseWindow(#ProgressForm) ;<== aucun effet

EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ShowProgress()  
  CreateThread(@Count(), #Null) 
  
  Repeat
    WindowEvent = WaitWindowEvent()
    
    Select WindowEvent
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
    
  ForEver
EndIf
Dernière modification par falsam le ven. 20/avr./2012 18:47, modifié 1 fois.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
dayvid
Messages : 1242
Inscription : mer. 11/nov./2009 18:17
Localisation : Poitiers (Vienne)

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par dayvid »

Edit: Grillé par Atland :lol:
Dernière modification par dayvid le jeu. 19/avr./2012 22:45, modifié 2 fois.
La vie, C'est comme, Une boitte, De startis, On en voie, De toutes, Les couleurs !

Mon forum http://purebasic.forumphp3.com/index.php
Avatar de l’utilisateur
Atlante
Messages : 337
Inscription : mer. 29/juin/2011 18:35
Localisation : Paris

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Atlante »

Donc en fait tu as fait l'erreur de gérer ton GUI dans plusieurs procédures, il faut absolument éviter quand tu travailles sur du thread.
Tu devrais utiliser les thread uniquement pour du calcul et te servir de variable globale pour gérer ta barre de progression par exemple.
Ce n'est rien de bien méchant ;)

Pour le code je te montre juste qu'en supprimant ta procédure pour ouvrir la fenêtre tout va bien.

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
  #ProgressForm
  #Progress
EndEnumeration

Define WindowEvent


;Le thread
Procedure Count(Value)
  Protected i.i
  OpenWindow(#ProgressForm, 0, 0, 200, 100, "", #PB_Window_ScreenCentered, WindowID(#Mainform))
  ProgressBarGadget(#Progress, 5, 40, 190, 20, 0, 100) 
  For i=1 To 1000
    SetGadgetState(#Progress, i/10)
  Next  

  CloseWindow(#ProgressForm) ;<== aucun effet

EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  CreateThread(@Count(), #Null) 
  
  Repeat
    WindowEvent = WaitWindowEvent()
    
    Select WindowEvent
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
    
  ForEver
EndIf
Cordialement.
atlante

Ps : désolé pour les fautes je go dodo je suis explosé
Modérateur
Config : Intel I5 4670K, Nvidia Geforce GTX 1060, 16go RAM, SSD 256go, DD 2000go
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par PAPIPP »

Bonjour Falsam

Peut être comme cela

Code : Tout sélectionner

EnableExplicit

Enumeration
	#MainForm
	#ProgressForm
	#Progress
EndEnumeration
Global thread, fin
Define WindowEvent


;Le thread
Procedure Count(Value)
  Protected i.i
  OpenWindow(#ProgressForm,0,0,200,100,"",#PB_Window_ScreenCentered,WindowID(#Mainform))
  ProgressBarGadget(#Progress,5,40,190,20,0,100)
	For i=1 To 1000
	  Delay(5)
		SetGadgetState(#Progress,i/10)
	Next
	fin=1
;   KillThread(thread)
CloseWindow(#ProgressForm) ;<== aucun effet

EndProcedure


If OpenWindow(0,0,0,300,300,"Window",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	
;   ShowProgress()

	thread=CreateThread(@Count(),#Null)
	Repeat
		WindowEvent=WaitWindowEvent()
		Select WindowEvent
			Case #PB_Event_CloseWindow
				End
				
		EndSelect
		
	ForEver
EndIf
A+ pas assez rapide même remarque que Atlante
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par falsam »

Merci pour ces 3 exemples mais malheureusement les 2 premiers ferment la fenêtre avant la fin de l'affichage de la jauge. Le 3eme exemple ne fait que retarder la fermeture de la fenêtre grâce à un delay.

ça ne m'explique pas pourquoi CloseWindow(#ProgressForm) reste sans effet.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Atlante
Messages : 337
Inscription : mer. 29/juin/2011 18:35
Localisation : Paris

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Atlante »

falsam a écrit :Merci pour ces 3 exemples mais malheureusement les 2 premiers ferment la fenêtre avant la fin de l'affichage de la jauge. Le 3eme exemple ne fait que retarder la fermeture de la fenêtre grâce à un delay.

ça ne m'explique pas pourquoi CloseWindow(#ProgressForm) reste sans effet.
Si, je te l'ai dit. Il ne faut pas gérer ta GUI (Graphical user interface) avec un thread.
Dans le thread il ne doit pas y avoir de gadget ou autre, le plus propre et surtout se qui te poseras le moins de problème :

Dans ton thread tu modifies une variable globale qui sera par exemple ta barre de progression.
Et dans ton programme principale, là tu récupères la valeur globale pour modifier le gadget.
Je te fais ça vite fais xd

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
  #ProgressForm
  #Progress
EndEnumeration

Define WindowEvent
Global i.i


;Le thread
Procedure Count(Value)

 
  For i=1 To 1000
Delay(50)
  Next  
 ;<== aucun effet

EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   OpenWindow(#ProgressForm, 0, 0, 200, 100, "", #PB_Window_ScreenCentered, WindowID(#Mainform))
    ProgressBarGadget(#Progress, 5, 40, 190, 20, 0, 100) 
  CreateThread(@Count(), #Null) ; pour ton calcul
  
  Repeat
    
    If i<1000 And i>0
      SetGadgetState(#Progress, i/10)
      Debug i/10
    ElseIf i=1000
      Debug i/10
      Delay(1000)
      CloseWindow(#ProgressForm)
      i=0
      EndIf
    
    WindowEvent = WaitWindowEvent()
    
    Select WindowEvent
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
    
  ForEver
EndIf
désolé là c'est codé à l'arrache, je go dodo je réponds demain si besoin ;)
A oui j'ai mis delay 50 dans la boucle car la fenetre se ferme trop vite car le gadget n'arrive pas à suivre sinon.
Même un delay 5 est trop petit ;)
Modérateur
Config : Intel I5 4670K, Nvidia Geforce GTX 1060, 16go RAM, SSD 256go, DD 2000go
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Backup »

en plus evite ce genre de truc :

Code : Tout sélectionner

Define WindowEvent
WindowEvent fait parti des mot clef de purebasic ! c'est une fonction , pas une variable ! :?

voir doc : Event = WindowEvent()

c'est vraiment pas l'ideal pour t'y retrouver ....
zaphod
Messages : 135
Inscription : dim. 07/déc./2008 9:32

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par zaphod »

Salut,

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
  #ProgressForm
  #Progress
EndEnumeration

Define WE.i,thread.i

;Affichage de la boite de dialogue de progression
Procedure ShowProgress()
  OpenWindow(#ProgressForm, 0, 0, 200, 100, "aa", #PB_Window_ScreenCentered, WindowID(#Mainform))
  ProgressBarGadget(#Progress, 5, 40, 190, 20, 0, 100) 
EndProcedure

;Le thread
Procedure Compte(*Value)
  Protected i.i
  For i=1 To 1000
    SetGadgetState(#Progress, i/10)
  Next  
  
EndProcedure


If OpenWindow(#mainform, 0, 0, 300, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ShowProgress()  
  thread=CreateThread(@Compte(), #Null) 
  
  Repeat
    WE = WaitWindowEvent()
    
    If IsThread(thread)=0
      CloseWindow(#ProgressForm)
    EndIf
    ;
    Select WE
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
    
  ForEver
EndIf


dayvid
Messages : 1242
Inscription : mer. 11/nov./2009 18:17
Localisation : Poitiers (Vienne)

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par dayvid »

Je sais bien que je suis très mal placer pour dire ceci et que je vais surement me faire jeter :oops: :
WindowEvent fait parti des mot clef de purebasic !

Je ne croix pas non mon cher dobro :|
Là c'est juste une variable comme tu l'as écrie non ?!
WindowEvent() oui et ce n'est absolument pas un mot clé mais bien une fonction non ?!
c'est une fonction , pas une variable !
Tous faux :!:
C'est bien une variable ici !!! :wink:

Il a bien écrie ceci:

Code : Tout sélectionner

Define WindowEvent
Et pas:

Code : Tout sélectionner

Define WindowEvent()
:mrgreen:

Certes, ça ne sert à rien à mon sens quoique :?
Il définit juste ça variable ?!

Mais je pense que ça ne sert a rien là comme il a fait non ?!
Autant faire:

Code : Tout sélectionner

WindowEvent.l = 0
Mais comme il a fait ça marche aussi, en plus s'il souhaite définir plusieurs variable en même temps, sa façon est correcte je pense !
On peu faire aussi:

Code : Tout sélectionner

Define.l WindowEvent
Ou même:

Code : Tout sélectionner

Define WindowEvent.l
Et même:

Code : Tout sélectionner

Define WindowEvent = 0
Ou

Code : Tout sélectionner

Define.l WindowEvent = 0
Ou

Code : Tout sélectionner

Define WindowEvent.l = 0
Les cinque fonctionne bien :)

Cependant je te rejoins mon cher Dobro quand tu disais que le mot clé:

Code : Tout sélectionner

Define
Ne sert à rien ou presque !

Il est plus utile dans ses circonstances car il économise des lignes de code:

Code : Tout sélectionner

Define.l, A, B, C, D
Etc., Ou:

Code : Tout sélectionner

Define A.l, B.I, C.d, D.f
Enfin c'est juste mon point de vue hein ! :) :wink:
La vie, C'est comme, Une boitte, De startis, On en voie, De toutes, Les couleurs !

Mon forum http://purebasic.forumphp3.com/index.php
Avatar de l’utilisateur
Mindphazer
Messages : 694
Inscription : mer. 24/août/2005 10:42

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Mindphazer »

dayvid a écrit :Je sais bien que je suis très mal placer pour dire ceci et que je vais surement me faire jeter :oops: :
WindowEvent fait parti des mot clef de purebasic !

Je ne croix pas non mon cher dobro :|
Là c'est juste une variable comme tu l'as écrie non ?!
WindowEvent() oui et ce n'est absolument pas un mot clé mais bien une fonction non ?!
c'est une fonction , pas une variable !
Tous faux :!:
C'est bien une variable ici !!! :wink:

Il a bien écrie ceci:

Code : Tout sélectionner

Define WindowEvent
Et pas:

Code : Tout sélectionner

Define WindowEvent()
:mrgreen:

Certes, ça ne sert à rien à mon sens quoique :?
Il définit juste ça variable ?!

Mais je pense que ça ne sert a rien là comme il a fait non ?!
Autant faire:

Code : Tout sélectionner

WindowEvent.l = 0
Mais comme il a fait ça marche aussi, en plus s'il souhaite définir plusieurs variable en même temps, sa façon est correcte je pense !
On peu faire aussi:

Code : Tout sélectionner

Define.l WindowEvent
Ou même:

Code : Tout sélectionner

Define WindowEvent.l
Et même:

Code : Tout sélectionner

Define WindowEvent = 0
Ou

Code : Tout sélectionner

Define.l WindowEvent = 0
Ou

Code : Tout sélectionner

Define WindowEvent.l = 0
Les cinque fonctionne bien :)

Cependant je te rejoins mon cher Dobro quand tu disais que le mot clé:

Code : Tout sélectionner

Define
Ne sert à rien ou presque !

Il est plus utile dans ses circonstances car il économise des lignes de code:

Code : Tout sélectionner

Define.l, A, B, C, D
Etc., Ou:

Code : Tout sélectionner

Define A.l, B.I, C.d, D.f
Enfin c'est juste mon point de vue hein ! :) :wink:
Ce que Dobro voulait dire, à mon sens, c'est que le fait que dans un prog il y ait une fonction ET une variable ayant le même nom (ce qui en soi n'est pas interdit, chacun fait comme il veut) peut entraîner des confusions lors de la relecture de ce code.
Bureau : Win10 64bits
Maison : Macbook Pro M3 16" SSD 512 Go / Ram 24 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
dayvid
Messages : 1242
Inscription : mer. 11/nov./2009 18:17
Localisation : Poitiers (Vienne)

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par dayvid »

Ce que Dobro voulait dire, à mon sens, c'est que le fait que dans un prog il y ait une fonction ET une variable ayant le même nom (ce qui en soi n'est pas interdit, chacun fait comme il veut) peut entraîner des confusions lors de la relecture de ce code.
Je suis 100% d'accord avec ça :) :wink:
La vie, C'est comme, Une boitte, De startis, On en voie, De toutes, Les couleurs !

Mon forum http://purebasic.forumphp3.com/index.php
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Backup »

Mindphazer a écrit : Ce que Dobro voulait dire, à mon sens, c'est que le fait que dans un prog il y ait une fonction ET une variable ayant le même nom (ce qui en soi n'est pas interdit, chacun fait comme il veut) peut entraîner des confusions lors de la relecture de ce code.

tout a fait :)

ce qui fait qu'on s'y retrouve dans un code , c'est d'avoir un minimum de discipline

( on a fait un topic sur la beauté du code.. a lire c'est tres tres important.. surtout pour les débutants.. mais pas seulement :) )
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par falsam »

@zaphod : Merci pour ton code mais chez moi il plante à la fermeture de la fenêtre à la ligne 36

Code : Tout sélectionner

CloseWindow(#ProgressForm)
Message du compilateur [ERREUR] le #Window spécifié n'est pas initialisé
Étonnant comme message car le fenêtre est bien initialisée.

@Dobro : Tu as raison d'autant plus que je le reproche aussi :p. Même si ça n'a aucune importance sur la compilation, pour plus de clarté évitons de déclarer des variables s'écrivant de la même manière que les mots réserver de Pure Basic.

Finalement j'ai adopté la solution suivante

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
  #Buffer
  #ProgressForm
  #Progress
EndEnumeration

Global Thread, EndThread

Define WEvent

;Le thread
Procedure Count(Value)
  Protected i.i
  
  If OpenWindow(#ProgressForm, 0, 0, 200, 100, "", #PB_Window_ScreenCentered, WindowID(#Mainform))
    ProgressBarGadget(#Progress, 5, 40, 190, 20, 0, 100)

    For i=10 To 1000
      Delay(10)
      SetGadgetState(#Progress, i/10)
      SetGadgetText(#Buffer, Str(i))
    Next  
    SetGadgetState(#Progress, 100)
    Delay(1000)
    SetGadgetState(#Progress, 100)
    EndThread=1
  EndIf
EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(#buffer,10, 10, 100, 20, "?")
  Thread=CreateThread(@Count(), 100) 
  
  Repeat
    WEvent = WaitWindowEvent()

    Select WEvent
      Case #PB_Event_CloseWindow
        End
        
      Default
        If EndThread=1 And IsWindow(#ProgressForm)
          SetActiveWindow(#Mainform)
          CloseWindow(#ProgressForm)
        EndIf
        
    EndSelect
  
  ForEver
EndIf
La gestion des delay() afin de permettre au ProgressBarGadget() de se mettre à jour correctement.
Commentez les Delay() pour voir la différence.

Merci de votre aide :) je note le sujet comme résolu mais la discussion continue si besoin est .....
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Atlante
Messages : 337
Inscription : mer. 29/juin/2011 18:35
Localisation : Paris

Re: Fenetre qui ne se ferme pas depuis un Thread

Message par Atlante »

falsam a écrit : La gestion des delay() afin de permettre au ProgressBarGadget() de se mettre à jour correctement.
Commentez les Delay() pour voir la différence.

Merci de votre aide :) je note le sujet comme résolu mais la discussion continue si besoin est .....
C'est ce que j’avais marqué en dessous de mon code.
Mais essayes d'éviter de gérer les gadgets dans dans des thread, mettre des delay a chaque fois c'est du bricolage.
Cela ne sera qu'une source de problème dans le temps crois moi.
Bonne continuation.
Modérateur
Config : Intel I5 4670K, Nvidia Geforce GTX 1060, 16go RAM, SSD 256go, DD 2000go
Répondre