Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.10.2011, 21:45   #1
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
Печаль Отстает секундомер

Вот сделал секундомер. Запустил и думаю: что-то медленно секунды идут. Взял телефон и одновременно запустил. Когда на компьютере было ~10 секунд, на телефоне ~20. Процессор сильно не грузится (меньше 0%).
Где ошибка или недочет?


Код:
unit super_sek_;

interface

uses
  Windows, SysUtils, Forms,
  ExtCtrls, StdCtrls, Dialogs, Controls, Classes;

type
  TForm1 = class(TForm)
    ButtonSS: TButton;
    ButtonReset: TButton;
    LabelMin: TLabel;
    LabelSec: TLabel;
    LabelDsec: TLabel;
    LabelDvoet1: TLabel;
    LabelTochka: TLabel;
    Shape1: TShape;
    Timer1: TTimer;
    LabelHour: TLabel;
    LabelDvoet2: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure ButtonSSClick(Sender: TObject);
    procedure ButtonResetClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

var
  hour: integer;     // часы
  min:  integer;     // минуты
  sec:  integer;     // секунды
  dsec: integer;     // сотые секунды

// сигнал от таймера
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  inc(dsec);
  if dsec < 100 then
  begin
    if dsec < 10
        then LabelDsec.Caption := '0' + IntToStr(dsec)
        else LabelDsec.Caption := IntToStr(dsec);
    exit;
  end
  else
  // надо увеличить кол-во секунд
  dsec := 0;
  labelDsec.Caption := '00';

  sec := sec + 1;
  if sec < 60 then
    begin
      if sec < 10 then
        LabelSec.Caption := '0' + IntToStr(sec)
      else
        LabelSec.Caption := IntToStr(sec);
      exit;  // кол-во минут увеличивать не надо
    end

  else
    // надо увеличить минуты
    sec :=0;
    labelMin.Caption := '00';

    min := min + 1;

  if min < 60 then
    begin
      if min < 10 then
        LabelMin.Caption := '0' + IntToStr(sec)
      else
        LabelMin.Caption := IntToStr(sec);
      exit;  // кол-во часов увеличивать не надо
    end
  else
    // надо увеличить часы
    min :=0;
    labelHour.Caption := '00';

    hour := hour + 1;

    if hour < 99 then
       if hour < 10 then
            LabelHour.Caption := '0' + IntToStr(min)
       else
            LabelHour.Caption := IntToStr(min)
    else // максимальный интервал - 99 мин
        begin
           Timer1.Enabled := False; // остановить секундомер
           ShowMessage('Измерить интервал больше 59:59.99 нельзя.');
           ButtonSS.Caption := 'Пуск';
           Form1.ButtonResetClick(sender);
        end;
end;

// щелчок на кнопке Пуск/Стоп
procedure TForm1.ButtonSSClick(Sender: TObject);
begin
  if Timer1.Enabled then
  begin
     // счет времени
     Timer1.Enabled := False; // остановить секундомер
     ButtonSS.Caption := 'Пуск';
     ButtonReset.SetFocus;
  end
  else begin
     // секундомер стоит
     Timer1.Enabled := True;    // пуск таймера
     ButtonSS.Caption := 'Стоп';
  end;
end;

// щелчок на кнопке Сброс
procedure TForm1.ButtonResetClick(Sender: TObject);
begin
   hour:=0;
   min := 0;
   sec := 0;
   dsec := 0;
   // индикатор в исходное состояние
   LabelDsec.Caption := '00';
   LabelSec.Caption := '00';
   LabelMin.Caption := '00';
   LabelHour.Caption := '00';
   if NOT Timer1.Enabled then ButtonSS.SetFocus;
end;

// обработка события OnCreate
procedure TForm1.FormCreate(Sender: TObject);
begin
   min  := 0;
   sec  := 0;
   dsec := 0;
   Timer1.Enabled  := False;
   Timer1.Interval := 10; // сигнал от таймера через 0,01 сек
end;

end.
Форма в прикреплении, т.к. макс. размер сообщения 5000 знаков.
Вложения
Тип файла: rar super_sek_.rar (579 байт, 17 просмотров)
hon вне форума Ответить с цитированием
Старый 01.10.2011, 21:50   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Запоминай перед стартом таймера текущее время, по тику таймера определяй разницу между текущим и тем, что запомнил - наиболее точный способ определения интервала времени
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.10.2011, 22:12   #3
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Запоминай перед стартом таймера текущее время, по тику таймера определяй разницу между текущим и тем, что запомнил - наиболее точный способ определения интервала времени
как? пример, пожалуйста.
hon вне форума Ответить с цитированием
Старый 01.10.2011, 22:21   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  lTime:=Now;
  Label1.Caption:=Format('Старт: %s',[FormatDateTime('hh:nn:ss',lTime)]);
  Timer1.Interval:=200;  //здесь сам задай необходимый интервал
  Timer1.Enabled:=True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label2.Caption:=Format('Прошло: %s',[FormatDateTime('hh:nn:ss',Now-lTime)]);
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.10.2011, 14:11   #5
JUDAS
фонатик DELPHI
Форумчанин
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Сообщений: 714
По умолчанию

hon попробуй этот вариант
Код:
var
 Start : TDateTime;

procedure TForm1.Timer1Timer(Sender: TObject);
var S : string;
begin
  S:= FormatDateTime('hh:nn:ss:zzz',Now - Start);
  LabelHour.Caption:=Copy(S,1,2);
  LabelMin.Caption:=Copy(S,4,2);
  LabelSec.Caption:=Copy(S,7,2);
  LabelDsec.Caption:=Copy(S,10,3);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Start := Now;
 Timer1.Enabled:=not Timer1.Enabled;
end;
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума Ответить с цитированием
Старый 02.10.2011, 14:36   #6
_Dmitry
Участник клуба
 
Аватар для _Dmitry
 
Регистрация: 02.09.2007
Сообщений: 1,193
По умолчанию

Дельфийский таймер будет отставать в любом случае.
Для точного отсчета времени используйте мультимедийный таймер.
Тема уже рассматривалась: http://www.programmersforum.ru/showthread.php?t=12132
И даже был пример сравнения таймеров: http://www.programmersforum.ru/showp...6&postcount=29
_Dmitry вне форума Ответить с цитированием
Старый 02.10.2011, 14:40   #7
JUDAS
фонатик DELPHI
Форумчанин
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Сообщений: 714
По умолчанию

Цитата:
Дельфийский таймер будет отставать в любом случае.
в случае с кодом подобным Аватар и моему - никакого отсавания не будет.
Наши с Аватаром коды не считают "тики процессора", которые зависят от производительности ОС в определённый момент времени, а считаем системное время.
Если даже произойдёт заторможенность в определённый момент, то в следующем тике будет отработана разница между Now и значением Start которое запоминается при старте )
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума Ответить с цитированием
Старый 03.10.2011, 09:59   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Дельфийский таймер будет отставать в любом случае.
ну да, конечно.
учитывая что Дельфийский не более чем обертка над АПИшным.

первое что бросилось в глаза, у вас код громоздок, подумайте сами, успевает ли он выполнится за ваш интервал?(+учитывая что после выполнения кода таймера у вас будет перерисовка лейблов с новыми значениями(а то и всей формы, я не знаю как это у VCL реализовано))
рано или поздно будет отставание.

да и кстати, пожалуй GetTickCount тут достаточно будет.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Секундомер на С++!!! JOHNY26RUS Помощь студентам 4 26.05.2011 11:13
Секундомер aesoem Общие вопросы Delphi 10 28.01.2008 19:25
секундомер itisiam Общие вопросы Delphi 6 31.05.2007 16:55