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

Langage Delphi Discussion :

Comment réaliser un chronomètre ?


Sujet :

Langage Delphi

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut Comment réaliser un chronomètre ?
    Bonjour

    J'ai un petit problème, je n'arrive pas à résoudre cet exercice:

    Développer un chronomètre qui peur être démarré, arrêté et mis à zéro. Le chronomètre mesure le temps en dixièmres de secondes. Utilisez une logique approprié pour l'activation et la désactivation des boutons que vous utilisez.

    J'ai déjà préparé la fiche mais je ne sais pas comment m'y prendre...

    Quelqu'un aurait la gentilesse de m'aider?

    theprimitive

  2. #2
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    744
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 744
    Points : 500
    Points
    500
    Par défaut
    Salut
    Essaye de regarder l'aide sur GetTickCount çà devrai te mettre sur la voie ...

    bye !
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Merci mais l'aide ne trouve rien

    Pourtant j'ai bien écrit GetTickCount mais sans résultats...

  4. #4
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    744
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 744
    Points : 500
    Points
    500
    Par défaut
    re ..
    voila un exemple qui te donne un top toute les 0,1 seconde

    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
     
     
    procedure TForm1.Button4Click(Sender: TObject);
    Var
        FHighPerf : Boolean ;
        HighFreq : Int64 ;
        Stop,Start : Int64 ;
        Resolution:real;
        CompteurTop:integer;
    begin
        fini:=false;
       compteurTop=0;
        Resolution:=0.1; // base seconde donc resolution du top aux diziemes
        FHighPerf:=QueryPerformanceFrequency(HighFreq);
        If Not FHighPerf Then HighFreq:=1000;
        repeat
           If FHighPerf Then QueryPerformanceCounter(Start) Else Start:=GetTickCount;
           repeat
              If FHighPerf Then QueryPerformanceCounter(Stop) Else Stop:=GetTickCount;
           until (Stop-Start)/HighFreq > Resolution;
           inc(compteurTop);
     
           //===========
           // ici tu as un top tout les dixieme
           //===========
     
        until fini;
    end;
    bye et bonne continuation .
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bonjour,

    Ne serait il pas plus simple d'utiliser un TTimer. Il encapsule les API windows.

    Le TTimer est un composant déclenchant un evenement (OnTimer) à interval en principe régulier.

    1° mettez un TTImer sur une fiche
    2° mettez le enbled du timer à fause
    3° MEttez l'intervale à 100 (100 milliseconde)
    4° ajouter un boutton demarrage .
    Ce bouton stock le moment du declenchement (now) et m'est le timer à enabled := true

    5° ajouter un boutton d'arret . Ce bouton m' est le timer à enabled := false
    6° Ajouter un evenement OnTimer dans le timer
    6-1 Timer.enabled := False
    6-2 Calcule du temps écoulé depuis le début (temp stoké au début du decompte - now) et affichage
    6- 3Timer.Enabled := true

    Quelque explications:

    Pourquoi travailler avec l'heur stocker au lieu de compter les increment ?

    Le timer comme les api windows n'arréte pas le processus pour lancer un événement. Des que windows le peux, il déclenche l'évenement il peut donc avoir de léger décallage qui peuvent compter à la longue (le decallage est minime, en générale bien inférieure au millièmes de seconde, mais sur X heures cela peut compter)


    Pourquoi le enabled := false du timer ?


    Un risque avec un timer est qu'il peut déclencher plusieur fois un événement simulatnément

    exemple:
    Declenchement 1 du timer
    Le traitemen (1) est en cour d'execution
    Declenchement 2 du timer
    Le traitemen (2) est en cour d'execution
    Declenchement 3 du timer
    Le traitemen (3) est en cour d'execution
    Fin ddu declenchement (1) du timer.
    Declenchement 4du timer
    Le traitemen (4) est en cour d'execution

    Dans cette exemple l'évenement est plus long à traiter que le traitement de l'événément. Du coup l'application lance de plus en plus de traitements jusqu'au plantage final.

    NOTA 1:
    Pour éviter les risques avec les enabled protéger l'évenement avec un try finally

    NOTA 2:
    Le boutton d'arret est piégé.
    Il existe un risque notable:
    1° L'évenement OnTimer se declenche
    Donc Timer.enabled := False et debut du traitement
    2° Le traitement est long, par conséquence vous avez mis un processe message dans le traitement. Si vous appuyer sur arret vous mettez le timer à false (arret du timer)
    3° Fin de l'évenement, du coup le timer est remis a true. L'arret à été contourner.



    Il existe une autre solution.
    Dans le TApplication il y a un événement qui se declenche quand l'événement est en attente (entre 2 touche quand vous rentrer un text par exemple). vous pouvez utiliser cette événement pour tester votre temps.
    Atention danger, l'évenement vas être lancer trés souvent. Si votre traitement est longt vous ralentirez votre machine. De plus vous ne pouvez utiliser cette évenement qu'une seul fois dans l'application. si vous l'utiliser pour votre timer, il ne sera plus disponible pour autre chose.

  6. #6
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    merci bcp pour ta réponse

    Mais j'ai encore une petite question...

    Je ne comprends pas vraiment ce que je dois faire dans le point 6-2...

    Citation Envoyé par Tardiff Jean-François
    6-2 Calcule du temps écoulé depuis le début (temp stoké au début du decompte - now) et affichage
    Regarde...

    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
     
    procedure TForm1.btnStartClick(Sender: TObject);
    begin
    Timer.enabled:=true;
    end;
     
    procedure TForm1.btnStopClick(Sender: TObject);
    begin
    Timer.enabled:=false;
    end;
     
    procedure TForm1.TimerTimer(Sender: TObject);
    begin
    Timer.enabled:=false;
    Timer.enabled:=true;
    end;

  7. #7
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Une rq, l'aide sur getTickCount se trouve dans le Windows SDK, qui est distribué avec Delphi 7 Entreprise, je ne sais pas pour toi.

  8. #8
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    merci mais mon prof m'a dit de ne pas utiliser le GetTickCount...

    En plus il se trouve que j'ai encor une ancienne version de delphi c'est pour ça que je ne le trouve pas...

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 856
    Points : 11 290
    Points
    11 290
    Billets dans le blog
    6
    Par défaut
    J.F. Tardiff t'a parfaitement répondu :

    pour son point 6.2, tu stockes au démarrage du chrono la valeur du temps système (obtenu grâce à la fonction Now) dans une variable tps_start de type TDateTime et à l'arrêt du chrono, dans la variable tps_stop

    le temps écoulé est obtenu par différence (tps_stop - tps_start)

    il te suffit de l'afficher grâce à la fonction TimeToStr, en ayant formaté la chaîne au moyen de la variable LongTimeFormat (tu supprimeras les 2 digits de millisecondes excédentaires grâce aux fonctions traitant les chaînes et un petit arrondi)

    ton aide doit t'apporter suffisamment de renseignements sur toutes ces fonctions et types de variables !

    bon code
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  10. #10
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    je me suis déjà essayé à la réalisation d'un chrono avec un timer.
    mon chrono émettait un bip à intervalle régulier fixé par l'utilsateur.
    mais après utilisation et comparaison avec un chrono à quartz j'ai laissé tomber...au bout d'une utilisation prolongée un décalage dans le temps apparaît...il faut envisager une autre direction à mon avis.
    il faut pas se caler sur l'horloge windows.

  11. #11
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    744
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 744
    Points : 500
    Points
    500
    Par défaut
    j'avais donné la solution du GetTickCount et du QueryPerformanceFrequency pour avoir un maximum de precision .

    Le GetTickCount doit marcher même sur des versions inferieures a delphi7. ( et pourquoi ton prof veux pas que tu utilises cela ? )

    Le QueryPerformanceFrequency lui est fonction de l'OS ( de souvenir !! ).

    Par contre a mon avis , la precision de 100ms etant pas enorme la methode donné avec le timer devrai etre suffisante .

    L'aide delphi préconise aussi d'utiliser les fonctions TTimeStamp ...
    pour avoir une grande precision dans les routines de gestion des heures .. peut etre que çà peut aider aussi !

    bye !
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  12. #12
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    merci

    Ben je pense qu'il ne me manque plus beaucoup

    mais qu'est-ce qui manque encore???

    procedure TfrmMain.btnStartClick(Sender: TObject);
    var tps_start:TDateTime;
    begin
    Timer.enabled:=true;
    tps_start:=now;
    end;

    procedure TfrmMain.btnStopClick(Sender: TObject);
    var tps_stop:TDateTime;
    begin
    Timer.enabled:=false;
    tps_stop:=now;
    end;

    procedure TfrmMain.TimerTimer(Sender: TObject);
    var tps_start,tps_stop:TDateTime;
    LongTimeFormat:string;
    begin
    Timer.enabled := False;
    LongTimeFormat:= timetostr(tps_stop - tps_start);
    lblTime.Caption:=LongTimeFormat;
    Timer.Enabled := true;

  13. #13
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par theprimitive
    merci

    Ben je pense qu'il ne me manque plus beaucoup

    mais qu'est-ce qui manque encore???

    procedure TfrmMain.btnStartClick(Sender: TObject);
    var tps_start:TDateTime;
    begin
    Timer.enabled:=true;
    tps_start:=now;
    end;

    procedure TfrmMain.btnStopClick(Sender: TObject);
    var tps_stop:TDateTime;
    begin
    Timer.enabled:=false;
    tps_stop:=now;
    end;

    procedure TfrmMain.TimerTimer(Sender: TObject);
    var tps_start,tps_stop:TDateTime;
    LongTimeFormat:string;
    begin
    Timer.enabled := False;
    LongTimeFormat:= timetostr(tps_stop - tps_start);
    lblTime.Caption:=LongTimeFormat;
    Timer.Enabled := true;
    end;

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bonjour,

    Personellement je mettrait un Try finally pour protéger le enabled := True à la fin de l'événement du timer.

    Le risque de clique sur le bouton stop alors que l'événement du timer à lieu (la fin de l'évenement anulerait le stop) n'existe pas car la procédure est courte et ne contient pas d'application.Processmessage.

    En ce qui concerne Archimède et son essai avec un timer, je pense que le problème venait que vous tentiez de conter les impulsions. Dans ce cas il y a une dérive car le timer est en principe régulier mais en pratique aucun système informatique ne l'est. Le timer ne ce déclenche que lorque les taches en cours ne luis permette. Autrement dit, le système finit les instructions en cours avant de traiter le timer (il ce m'est dans un état "propre" avec des points de reprise pour reprendre la tache a la fin du timer).
    C'est pour cela qu'il faut stocker la date de départ et la comparer à la date en cour. Cela évite les décallages.

  15. #15
    Nouveau Candidat au Club
    Inscrit en
    Octobre 2005
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    procedure TfrmMain.btnStartClick(Sender: TObject);
    var tps_start:TDateTime;
    begin
    Timer.enabled:=true;
    tps_start:=now;
    end;

    procedure TfrmMain.btnStopClick(Sender: TObject);
    var tps_stop:TDateTime;
    begin
    Timer.enabled:=false;
    tps_stop:=now;
    end;

    procedure TfrmMain.TimerTimer(Sender: TObject);
    var tps_start,tps_stop:TDateTime;
    LongTimeFormat:string;
    begin
    Timer.enabled := False;
    LongTimeFormat:= timetostr(tps_stop - tps_start);
    lblTime.Caption:=LongTimeFormat;
    Timer.Enabled := true;
    Try finally

    end;
    Merci pour toutes les infos...

    mais le compteur ne démarre tjs pas

    mais ce que moi je ne comprend c'est comment le programme fait-il pour calculer le tps_stop - le tps_start (marqué en gras) puisque les deux variables ont été initialisé dans les deux procedures avant...

    Comment est-ce que je peut reprendre la valeur deux ces deux variables et est-ce qu'il y a d'autres fautes dans mon programme?

  16. #16
    Membre confirmé
    Avatar de lil_jam63
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 447
    Points : 600
    Points
    600
    Par défaut
    Tu t'y prend mal dans ton "analyse" du problème.
    Développer un chronomètre qui peur être démarré, arrêté et mis à zéro. Le chronomètre mesure le temps en dixièmres de secondes. Utilisez une logique approprié pour l'activation et la désactivation des boutons que vous utilisez.
    Il te faut pour commencer un timer qui remet à jour l'affichage tous les 10ème de secondes, pour celà le TTimer fera l'affaire.
    Il te faut donc un affichage de ce genre H:M:S:Ms ou juste S:Ms c'est à toi de voir.
    Ensuite, un bouton pour démarrer le comptage, un autre pour l'arreter, et enfin un 3ème pour remettre à 0 l'affichage.
    Pendant le comptage, les boutons start et remise à 0 doivent être désactivés et pendant l'arret, le bouton stop doit être désactivé.
    Je te donne pas de code mais juste des expliquations qui vont te permettre de comprendre ce que tu fais, c'est le but d'un cours.
    Pour répondre à ta question
    Comment est-ce que je peut reprendre la valeur deux ces deux variables et est-ce qu'il y a d'autres fautes dans mon programme?
    Tu déclares tes variables tps_start, tps_stop en local donc forcement les autres procedures n'y ont pas accès, pour celà déclare les en globale

    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
     
    unit1
     
    interface
     
    uses
      ... ;
     
    type
      ...
     
    var
      tps_start,tps_now:TDateTime;
     
    implementation
      ...
    ensuite tu les utilisent comme tu fais actuellement.
    Pour t'aider, je vais juste te donner le code de l'evenement onTimer de ton Timer, pour le reste je te laisse reflechir un peu.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure TForm1.TimerTimer(Sender: TObject);
    var
      Hour, Min, Sec, MSec: Word;
    begin
      tps_now := now; // on récupère la date et l'heure actuel
      DecodeTime((tps_now - tps_start), Hour, Min, Sec, MSec); // on calcule le temps écoulé depuis la référence (tps_Start - tps_now) et on extrait les infos (H, M, S, Ms ) F1 sur DecodeTime pour plus d'infos
      lblTime.Caption:=intToStr(Hour)+'Hr '+intToStr(Min)+'Min '+intToStr(Sec)+'Sec '+intToStr(MSec)+'Ms'; // on construit notre affichage et on l'affiche
    end;
    Pour le reste essaye de reflechir un p'tit peu, c'est très facile, agit sur les propriétés Enabled des boutons pour les activer ou désactiver.
    ----------------------------------------------------
    Avant de poster, pensez à utiliser les différents outils à votre disposition:
    Google, la FAQ et le moteur de recherche.

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2002
    Messages : 16
    Points : 19
    Points
    19
    Par défaut
    lil_jam63 a très bien résumé ton problème.

    Juste un petit supplément. Pour l'affichage tu peux aussi utiliser la fonction FormatDateTime, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.TimerTimer(Sender: TObject); 
    begin 
      lblTime.Caption := FormatDateTime('hh:nn:ss:zzz', tps_now - tps_start);
    end;

  18. #18
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Citation Envoyé par lil_jam63
    Pour le reste essaye de reflechir un p'tit peu, c'est très facile, agit sur les propriétés Enabled des boutons pour les activer ou désactiver.
    ou utilise le meme bouton en changant son caption et utlise la proprité tag ou un variable pour le changé selon l'état actuelle
    lil_jem peut vs donnée plus d'info
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bobour,

    L'événement OnTimer est bien attribué à TimerTimer ?

Discussions similaires

  1. msi ou comment réaliser un installeur?
    Par herzleid dans le forum Delphi
    Réponses: 11
    Dernier message: 09/04/2007, 19h27
  2. [FLASH MX] Comment réaliser une forme dentelée
    Par celina5880 dans le forum Flash
    Réponses: 4
    Dernier message: 04/11/2004, 17h48
  3. [DBGrid avec Cumul]Comment réaliser un cumul dans un DBGrid
    Par Eric SAULNIER dans le forum Bases de données
    Réponses: 2
    Dernier message: 21/07/2004, 17h56
  4. Comment réaliser des modèles de documentations avec XML ?
    Par Dams76 dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 29/08/2003, 02h15

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