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

Delphi Discussion :

Créer une barre de progression avec "stop/pause"


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 35
    Points : 22
    Points
    22
    Par défaut Créer une barre de progression avec "stop/pause"
    Bonjour!
    voila je voudrais créer une fiche sur laquelle j'ai une barre de progression que j'appel lors d'un chargement ou d'un traitement prolongé.

    Je voudrais lier a ces barres, un bouton "stop" qui coupe le traitement et un bouton "pause" qui met le traitement en attente.

    Comment puis je réaliser ceci?

    Pour le "pause" j'ai pensé stocker la possiton de la barre lors du clic puis de relancer le traitement via la donnée stocké.
    Qu'en pensez vous?

  2. #2
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    En fait, tout dépend si cette progression est fonction du temps ou fonction d'une suite opérations à effectuer. Dans le cas du temps, utilise un timer pour actualiser l'affichage, la position de la progression. Utilise ensuite Timer1.Enabled pour mettre en route ou arrêter. De tête, voici un exemple pour avoir une barre de progression de 30 secondes. Elle sera, par exemple, actualisée 4 fois par seconde pour obtenir une progression plus fluide :
    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
    Procedure TForm1.FormCreate(Sender: TObject);
    Begin
      Button1.Caption := 'Start';
      Timer1.Enabled := False;
      Timer1.Interval := 1000 Div 4;  // 250ms
      Gauge1.Max := 30000 * 4;  // 30 secondes
      Gauge1.Progress := 0;
    End;
     
    Procedure TForm1.Button1Click(Sender: TObject);
    Begin 
      Timer1.Enabled := Not Timer1.Enabled;
      If (Timer1.Enabled) Then 
        Button1.Caption := 'Stop' Else
        Button1.Caption := 'Start';
    End;
     
    Procedure TForm1.Timer1Timer(Sender: TObject);
    Begin 
       Gauge1.Progress := Gauge1.Progress + 1;
       If (Gauge1.Progress >= Gauge1.Max) Then Button1Click(Nil);
    End;
    De retour parmis vous après 10 ans!!

  3. #3
    Teo
    Teo est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 110
    Points : 111
    Points
    111
    Par défaut
    Bonjour

    J'ai fait une fiche similaire il y a qlq années. Elle depend d'une suite d'opérations.
    Voici sommairement comment la mienne fonctionne(je l'utilise toujours mais je saisi plus trop comment elle fonctionne vraiment dans ces entrailles).

    La Fiche est dans une Unit(la unit possede une partie initialise qui force la fiche a Nil)
    sa création est dynamique pendant l'execution.
    J'ai des fonctions qui interagissent avec la fiche.
    Pas de "ShowModal"
    J'avais au moins un TTimer, puis il me semble y avoir ajouter au moins un Tthread. pour afficher l'heure, et un chrono pendant l'execution de la fenetre d'attente(mise a jour)

    Quand j'ai une appli qui doit faire un long traitement, dont je connais le nombre d'iterations(le nombre de boucles, de cycles, le nombre d'enregistrement a traiter) je procede ainsi

    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
     
    Procedure FichePrincipale.TraitementLong;
    Begin
      ...
      Pt_Enreg := Point(0,Query.RecordCount)
      Fiche_Attendez_Creation(Self,"Comptage des voix en cours...",0,Nbr_Enreg)
      While Not Query.Eof Do
      Begin
        Inc(Pt_Enreg.X);
        ....
        If Fiche_Attendez_MAJ_ArretDemander(Pt_Enreg.X)
        Then Begin
          //Arret demandez par utilisateur
          Break;
        End;
        Query.Next;
      End
      Fiche_Attendez_Detruire;
      ...  
    End;
     
    //
     
      Fiche_Attendez_Creation(Form:TForm;Msg:String;Indice_Depart,Indice_Max:Integer);
    Begin
      Fiche_Attendez := TFiche_Attendez.Create(Application);
      Fiche_Attendez.Init(Form,Msg,Indice_depart,Indice_Max);  
    End;
     
    Procedure Fiche_Attendez.Init(Form:TForm;Msg:String;Indice_Depart,Indice_Max:Integer);
    Begin
      Desactiver_Composants_Fiche(Form);//Utilise GetControls pour mettre à Enabled := False, les principaux controls(boutton,checkbox,ListBox,TEdit,...) mais sauvegarde leur etat avant
      Lbl_Msg.Caption := Msg;
      Gauge.MinValue := 0;
      Gauge.Progress := Indice_Min;
      Gauge.MaxValue := Indice_Max;
      Show;
    End;
     
    Procedure Fiche_Attendez.Bt_PauseClick()
    Begin
      MsgBox("Pause demandée...");//Cette fenetre etant modale, on attends que l'utilisateur appuye sur Ok, puis le traitement reprendra
    End;
     
    Procedure Fiche_Attendez.Bt_StopClick()
    Begin
      Bt_Stop.Tag := 1;
    End;
     
    Fonction Fiche_Attendez_MAJ_ArretDemander(Indice_Progress:Integer):Boolean;
    Begin
      if Fiche_Attendez = Nil Then Exit
      With Fiche_Attendez Do
      Begin
        Gauge.Progress := Indice_Progress;
        If Bt_Stop.Tag = 1
        Then Begin
          Return := True;
         //Le bouton Stop a ete pressé
        End;
        Else return := False
      End;
    End;
    Si La fiche d'attente est modal, on peut plus acceder a la fiche appelante,
    et le traitement initial s'interromp.

    J'ai un Timer qui affiche l'heure et le chrono afin de montrer que le temps s'ecoule, et que ca travaille.
    Plus il y a de Application.ProcessMesages, plus le rafraichissement du Lbl_Heure se fera

    Dans le code de la destruction de la fiche d'attente on remet a true, tous les Controls.Enabled de la fiche appelante

    C'est peut etre une piste - si j'ai pas été trop confus

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    Alors ma barre de progression est lié à des succession d'opérations (interogation dune base de données, ...).

    ALors j'ai regardé vaut proposition, elle semble interessante mais de mon coté j'ai pensé à utiliser les threads et d'interrompre l'éxécution via:
    - SuspendThread(GetCurrentThread) : pour le pause
    - ResumeThread(GetCurrentThread) : pour reprendre

    Question : si j'arrete le thread courant ( celui de l'application main je suppose) ma fenetre doit se bloquer. Est ce possible de ne pas figer la fenetre?
    L'identifiant du thread est il supprimer ou changer une fois le SuspendThread effectué?

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par davos56
    Question : si j'arrete le thread courant ( celui de l'application main je suppose) ma fenetre doit se bloquer. Est ce possible de ne pas figer la fenetre?
    L'identifiant du thread est il supprimer ou changer une fois le SuspendThread effectué?
    Si tu suspend le thread de la fenetre principale, ca devient impossible d'actualisé la fenêtre...Habituellement, on créer un nouveau thread et c'est
    dans celui-ci qu'on éffectue des tâches pour les-quelles on ne veut pas
    bloquer la fenêtre principale...

    SuspendThread() ne fait que suspendre l'execution d'un
    thread...il ne le suprime pas et ne le modifie en rien.

    J'ignore les résultats si on suspend un thread qui contient une connection
    ouverte avec un database... j'imagine que le liens sera éventuellement devenu invalide lors du resume...

    Malheureusement, je crois que ce ne sera pas aussi simple que Supend & Resume..

    Une piste:
    Je crois que tu dois faire fonctionner la mécanique de pause et reprise
    à l'intérieur de ton main... et une fois que tout ca fonctionne, tu pourras déplacer
    le traitement dans un thread...et ainsi ne plus bloquer ta fenêtre principale
    lors du traitement long...
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  6. #6
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Beurk ! "traitement prolongé" .>. "Barre de progression" .>. puis complications pour y ajouter des fonctions "stop" et "attend" (pour prolonger davantage le traitement prolongé?!)

    Comme le davos56 dit "je voudrais créer une fiche sur laquelle j'ai une barre de progression ..." il n'est peut-être pas trop tard :

    Est-on sûr que le code du "traitement prolongé" est suffisamment optimisé sous l'angle de la vitesse d'exécution ? plutôt que de se casser la tête avec toutes les complications précitées concernant la barre de progression qui stoppe ou qui dit attends ?

    L'Est-pas interdit de penser qu'il y a un truc tout bête qui cause la lenteur du traitement dit "prolongé" (exemple de truc bête : Form1.RichEdit1.Lines.Add() ou autre composant d'affichage ralentisseur mis à jour à chaque tour de boucle d'un traitement ... il y en a d'autres).
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  7. #7
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Il peut être intéressant dans certains cas de pouvoir interrompre un traitement, comme dans winzip par exemple. Perso, pour afficher la progression d'une suite d'opérations, j'incrémente la propriétés Progress du Gauge (ou une variable globale, ça dépend) à chaque fin d'opération. Par exemple, l'ajoût du filtre anti-aliasing dans mon jeu d'échecs lorsqu'on le redimensionne...

    J'ajoute aussi un TimeOut à l'aide d'un Timer si le thread est bloqué... (j'imagine que ça peut arriver)
    De retour parmis vous après 10 ans!!

  8. #8
    Membre expert
    Avatar de aityahia
    Homme Profil pro
    CIEPTAL CARS SPA
    Inscrit en
    Mars 2006
    Messages
    1 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Algérie

    Informations professionnelles :
    Activité : CIEPTAL CARS SPA
    Secteur : Transports

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 938
    Points : 3 329
    Points
    3 329
    Par défaut
    si ton traitement et placer dans une boucle il faut metre dans celle-ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.ProcessMessages
    pour que tes composant peuve avoir le focus a un mement données durant le traitement.

Discussions similaires

  1. Créer une barre de progression
    Par Downhill6 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 25/03/2009, 17h35
  2. EXCEL VBA - Créer une barre de progression
    Par babacool dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/08/2008, 18h16
  3. Réponses: 5
    Dernier message: 23/05/2008, 16h26
  4. Réponses: 9
    Dernier message: 24/03/2007, 22h37
  5. Créer une barre de progression sous Vba ??
    Par Deejoh dans le forum Général VBA
    Réponses: 7
    Dernier message: 17/10/2005, 15h05

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