How to make a Digital clock in delphi7?

Art Kristof picture Art Kristof · Feb 28, 2012 · Viewed 13.2k times · Source

I am pretty new to delphi , and would like to start with something easy . Could someone please show me an example how to make a Digital clock that will transfer the "time" ( hour , min , sec ) to a label ? Or something like that

Answer

Andreas Rejbrand picture Andreas Rejbrand · Feb 28, 2012

Exercise 1

Drop a TLabel and a TButton on your form.

Double-click the button, and write

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := TimeToStr(Time);
end;

Exercise 2

To get the time to update automatically, add a TTimer to your form, and double-click it (you can remove the button if you like). Then write

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := TimeToStr(Time);
end;

This code will run once a second (the default interval for a TTimer, which is perfect for us, so we do not need to change it).

Exercise 3

To make the clock more annoying, you can try this: in the interface of your form, add a private field called FHighlight, like this:

TForm1 = class(TForm)
  Button1: TButton;
  Label1: TLabel;
  Timer1: TTimer;
  procedure Button1Click(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
private
  { Private declarations }
  FHighlight: boolean;
public
  { Public declarations }
end;

Now you can do

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := TimeToStr(Time);
  if FHighlight then
  begin
    Label1.Color := clWhite;
    Label1.Font.Color := clBlack;
  end
  else
  begin
    Label1.Color := clBlack;
    Label1.Font.Color := clWhite;
  end;
  FHighlight := not FHighlight;
end;

In order for this effect to work, you need to change one of the properties of the TLabel control (design-time). Change Transparent to false, using the Object Inspector, if it isn't already.

Update (Exercise 4)

Since Warren P thinks it is too boring with a plain TLabel, this is how you can achieve a 'true' seven-segment digital clock:

procedure TForm1.FormPaint(Sender: TObject);
type
  TDigitData = array[0..6] of boolean;
  TPhysDigit = array[0..7] of TRect;
const
  DIGIT: array[0..9] of TDigitData =
    (
      (true, true, true, true, true, true, false),
      (false, true, true, false, false, false, false),
      (true, true, false, true, true, false, true),
      (true, true, true, true, false, false, true),
      (false, true, true, false, false, true, true),
      (true, false, true, true, false, true, true),
      (true, false, true, true, true, true, true),
      (true, true, true, false, false, false, false),
      (true, true, true, true, true, true, true),
      (true, true, true, true, false, true, true)
    );
var
  PaddingW,
  PaddingH,
  UnitX,
  UnitY,
  DigitWidth,
  DigitHeight,
  BarLengthX,
  BarLengthY,
  DigitSeparation,
  FieldSeparation: integer;
  SEGMENTS: array[0..5] of TPhysDigit;
  i: Integer;

  function TranslatePhysDigit(const PhysDigit: TPhysDigit; const DX: integer; const DY: integer = 0): TPhysDigit;
  var
    i: Integer;
  begin
    for i := 0 to 7 do
    begin
      result[i].Left := PhysDigit[i].Left + DX;
      result[i].Right := PhysDigit[i].Right + DX;
      result[i].Top := PhysDigit[i].Top + DY;
      result[i].Bottom := PhysDigit[i].Bottom + DY;
    end;
  end;

  procedure DrawDigit(const Position, Value: integer);
  var
    i: integer;
  begin
    for i := 0 to 6 do
      if DIGIT[Value, i] then
        Canvas.FillRect(SEGMENTS[Position, i]);
  end;

  procedure DrawColon(const Position: integer);
  var
    ColonRect1: TRect;
    ColonRect2: TRect;
  begin
    ColonRect1 := Rect(PaddingW + Position*UnitX, PaddingH + UnitY,
      PaddingW + (Position+1)*UnitX, PaddingH + 2*UnitY);
    ColonRect2 := Rect(PaddingW + Position*UnitX, PaddingH + 3*UnitY,
      PaddingW + (Position+1)*UnitX, PaddingH + 4*UnitY);
    Canvas.FillRect(ColonRect1);
    Canvas.FillRect(ColonRect2);
  end;

var
  t: string;

begin
  PaddingW := Width div 20;
  PaddingH := Height div 20;
  UnitX := (ClientWidth - 2*PaddingW) div 27;
  UnitY := (ClientHeight - 2*PaddingH) div 5;
  DigitWidth := 3*UnitX;
  DigitHeight := 5*UnitY;
  BarLengthX := 3*UnitX;
  BarLengthY := 3*UnitY;
  DigitSeparation := 4*UnitX;
  FieldSeparation := 6*UnitX;
  SEGMENTS[0, 0] := Rect(0, 0, DigitWidth, UnitY);
  SEGMENTS[0, 1] := Rect(DigitWidth - UnitX, 0, DigitWidth, BarLengthY);
  SEGMENTS[0, 2] := Rect(DigitWidth - UnitX, 2*UnitY, DigitWidth, DigitHeight);
  SEGMENTS[0, 3] := Rect(0, DigitHeight - UnitY, DigitWidth, DigitHeight);
  SEGMENTS[0, 4] := Rect(0, 2*UnitY, UnitX, DigitHeight);
  SEGMENTS[0, 5] := Rect(0, 0, UnitX, BarLengthY);
  SEGMENTS[0, 6] := Rect(0, 2*UnitY, DigitWidth, 3*UnitY);
  SEGMENTS[0] := TranslatePhysDigit(SEGMENTS[0], PaddingW, PaddingH);
  SEGMENTS[1] := TranslatePhysDigit(SEGMENTS[0], DigitSeparation);
  SEGMENTS[2] := TranslatePhysDigit(SEGMENTS[1], FieldSeparation);
  SEGMENTS[3] := TranslatePhysDigit(SEGMENTS[2], DigitSeparation);
  SEGMENTS[4] := TranslatePhysDigit(SEGMENTS[3], FieldSeparation);
  SEGMENTS[5] := TranslatePhysDigit(SEGMENTS[4], DigitSeparation);
  Canvas.Brush.Color := clBlack;
  Canvas.FillRect(ClientRect);
  Canvas.Brush.Color := clBlack;
  Canvas.FillRect(Rect(PaddingW, PaddingH, ClientWidth - PaddingW,
    ClientHeight - PaddingH));
  Canvas.Brush.Color := clRed;
  t := FormatDateTime('hhnnss', Time);

  for i := 0 to 5 do
    DrawDigit(i, StrToInt(Copy(t, i+1, 1)));

  if odd(StrToInt(Copy(t, 6, 1))) then
  begin
    DrawColon(8);
    DrawColon(18);
  end;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Invalidate;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Invalidate;
end;

Seven-segment digital clock

Playing with the GDI brushes:

Seven-segment digital clock