W dzisiejszym artykule przedstawię sposób na stworzenie prawdziwego zegara, takiego ze wskazówkami i z wyświetlaczem. Cały projekt oprzemy na DelphiX, bo najlepiej nadaje się do naszych celów. Zegar będzie miał trzy wskazówki, każda w innym kolorze, wskazująca godzinę będzie najkrótsza, a sekundy najdłuższa. Jako tło zalecam użycie jakiegoś obrazka przedstawiającego tarczę zegara o rozmiarze 256×256. Żebyście nie musieli się zbytnio przemęczać, dołączam do projektu gotowy obrazek, wykonany własnoręcznie.
Wstawmy na formę potrzebne komponenty:
TDXDraw – Name:draw, Width:256, Height:256
TDXImageList – Name: imagelist
TDXTimer – Name: timer, Interval: 1, ActiveOnly: false
Właściwość AutoSize formy ustawicie na true i BorderStyle na bsSingle. Dodajcie jeszcze rysunek tarczy do komponentu imagelist.
Teraz musimy przemyśleć, jak będziemy rysowali nasze wskazówki. Na tarczy zegara, wskazówka sekundowa ma zakres od 0-59, czyli 60 wartości, wskazówka minutowa to samo, ale zauważmy, że wskazówka godzinna nie ma 24 wartości, tylko na 12, i obraca się o dwa razy o 360 stopni w ciągu doby. Będziemy również potrzebowali trzech tablic, jednej do przechowywania informacji o aktualnym czasie, drugiej do przechowywania informacji o tym, o ile procent obrotu dana wskazówka się obróciła (to może być trochę niezrozumiałe, ale zaraz zobaczycie o co chodzi), i trzeciej do przechowywania stopnia obrotu wskazówki. Do pobrania aktualnego czasu użyjemy funkcji Time. Wszystko oczywiście umieścimy w procedurze OnTimer komponentu timer. Zadeklarujmy więc nasze zmienne i tablice:
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 |
var data:TDateTime; s:string; // czas w postaci stringa czas:array [1..3] of integer; wsp:array [1..3] of double; katy:array [1..3] of double Dodamy teraz wyświetlacz: draw.Surface.Fill(0); image.Items[0].Draw(draw.Surface,0,0,0); data:=time; s:=FormatDateTime('hh:mm:ss',time); draw.Surface.Canvas.Font.Name:='Courier New'; draw.Surface.Canvas.Font.Size:=13; draw.Surface.Canvas.Font.Color:=$eeeeee; draw.surface.canvas.Brush.Style:=bsclear; draw.Surface.Canvas.TextOut((draw.Surface.width-draw.Surface.Canvas.TextWidth(s)) div 2,(draw.Surface.height-draw.Surface.Canvas.TextHeight(s)) div 2+70,s); |
Teraz część najbardziej nas interesująca czyli obliczanie położenia wskazówek zegara. Najpierw musimy odpowiednio pociąć tekst i wsadzić informacje o czasie do komórek tablicy czas. Aha, jeszcze jedna uwaga dla nie obeznanych :), kąty podajemy w radianach, a nie w stopniach (2PI=360 stopni). Następnie obliczamy właśnie ten procent obrotu i na końcu obliczamy kąt obrotu wskazówki. Dziwicie się pewnie, dlaczego jeszcze odejmujemy PI/2 (90 stopni). Ano dlatego, że jak byśmy mieli normalnie 0 stopni, to by nam wskazówka wskazywała godzinę 3, a u nas 0 stopni musi być na godzinie 12, a godzina 3 musi mieć 90 stopni, więc musimy odjąć PI/2, żeby nam to dobrze wyszło. No i wreszcie rysowanie naszych wskazówek. Jak już wcześniej napisałem, każda ma inny kolor, grubość i długość. Do rysowania przyda się znajomość sinusów i cosinusów, bo bez tego nic nie zrobimy. Oto część dalsza procedury:
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 |
czas[1]:=strtoint(copy(s,1,2)); // godziny czas[2]:=strtoint(copy(s,4,2)); // minuty czas[3]:=strtoint(copy(s,7,2)); // sekundy wsp[1]:=czas[1]/12; wsp[2]:=czas[2]/60; wsp[3]:=czas[3]/60; katy[1]:=wsp[1]*2*Pi-Pi/2; katy[2]:=wsp[2]*2*Pi-Pi/2; katy[3]:=wsp[3]*2*Pi-Pi/2; draw.Surface.Canvas.Pen.Style:=psSolid; draw.surface.canvas.Pen.Color:=clRed; draw.Surface.Canvas.Pen.Width:=4; draw.Surface.Canvas.MoveTo(128,128); draw.Surface.Canvas.LineTo(128+round(100*cos(katy[3])),128+round(100*sin(katy[3]))); draw.surface.canvas.Pen.Color:=clBlue; draw.Surface.Canvas.Pen.Width:=5; draw.Surface.Canvas.MoveTo(128,128); draw.Surface.Canvas.LineTo(128+round(90*cos(katy[2])),128+round(90*sin(katy[2]))); draw.surface.canvas.Pen.Color:=clGreen; draw.Surface.Canvas.Pen.Width:=7; draw.Surface.Canvas.MoveTo(128,128); draw.Surface.Canvas.LineTo(128+round(70*cos(katy[1])),128+round(70*sin(katy[1]))); draw.Surface.Canvas.Release; draw.Flip; |
Jeszcze jedna rzecz. Dodając tego kod do zdarzenia OnCreate formy, zmienimy kształt naszej tarczy na okrągłą:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
procedure TForm1.FormCreate(Sender: TObject); var g:hrgn; begin g:=CreateEllipticRgn(0,0,256,256); SetWindowRgn(form1.Handle,g,true); end; |
Nie wiem czy się to komuś przyda, ale efekt wygląda ciekawie 🙂
Autor: krajew4