![]() |
Analoguhr
Ich habe ein Programm für eine Analoguhr geschrieben.
Es ist nur eine Übung gewesen, da ich noch Anfänger bin und mir Delpi selber beibringe. Ich würde mich freuen wenn ihr mal drüberschaut und sagt was ihr davon haltet. :spin2:
Delphi-Quellcode:
unit Uhr;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TAnaloguhr = class(TForm) Edit1: TEdit; Uhr: TTimer; procedure UhrTimer(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Analoguhr: TAnaloguhr; SecWinkel : integer; MinWinkel : Integer; StdWinkel : Integer; SecWinkelAlt : integer; MinWinkelAlt : integer; StdWinkelAlt : integer; Zeit : String; XPos : integer; YPos : Integer; Std : Integer; Min : Integer; Sec : Integer; implementation {$R *.dfm} procedure TAnaloguhr.UhrTimer(Sender: TObject); begin {---------------Systemzeit auslesen und zuweisen -------------------} Zeit := TimeToStr(Time); Edit1.Text := Zeit; Std := StrToInt(Copy(Zeit,1,2)); Min := StrToInt(Copy(Zeit,4,2)); Sec := StrToInt(Copy(Zeit,7,2)); {-------------Zeigerwinkel berechnen--------------------------------} SecWinkel := (( 6 * Sec)+90); MinWinkel := (( 6 * Min)+90); StdWinkel := ((30 * Std)+90); {------------Zeiger Löschen-----------------------------------------} {-------------Sekunde-----------------------------------------------} XPos := Trunc (cos(SecWinkelAlt * Pi /180) *(-100)); YPos := Trunc (sin(SecWinkelAlt * Pi /180) *(-100)); Canvas.MoveTo(150,150); Canvas.Pen.Color := clBtnFace; Canvas.Pen.Width := 1; Canvas.LineTo((XPos + 150),(YPos + 150)); {--------------Minuten---------------------------------------------} XPos := Trunc (cos(MinWinkelAlt * Pi /180) *(-100)); YPos := Trunc (sin(MinWinkelAlt * Pi /180) *(-100)); Canvas.MoveTo(150,150); Canvas.Pen.Color := clBtnFace; Canvas.Pen.Width := 3; Canvas.LineTo((XPos + 150),(YPos + 150)); {--------------Stunde----------------------------------------------} XPos := Trunc (cos(StdWinkelAlt * Pi /180) *(-80)); YPos := Trunc (sin(StdWinkelAlt * Pi /180) *(-80)); Canvas.MoveTo(150,150); Canvas.Pen.Color := clBtnFace; Canvas.Pen.Width := 3; Canvas.LineTo((XPos + 150),(YPos + 150)); {-------------Zeiger Zeichnen---------------------------------------} {-------------Sekunde-----------------------------------------------} XPos := Trunc (cos(SecWinkel * Pi /180) *(-100)); YPos := Trunc (sin(SecWinkel * Pi /180) *(-100)); Canvas.MoveTo(150,150); Canvas.Pen.Color := 0; Canvas.Pen.Width := 1; Canvas.LineTo((XPos + 150),(YPos + 150)); {--------------Minuten---------------------------------------------} XPos := Trunc (cos(MinWinkel * Pi /180) *(-100)); YPos := Trunc (sin(MinWinkel * Pi /180) *(-100)); Canvas.MoveTo(150,150); Canvas.Pen.Color := 0; Canvas.Pen.Width := 3; Canvas.LineTo((XPos + 150),(YPos + 150)); {--------------Stunde----------------------------------------------} XPos := Trunc (cos(StdWinkel * Pi /180) *(-80)); YPos := Trunc (sin(StdWinkel * Pi /180) *(-80)); Canvas.MoveTo(150,150); Canvas.Pen.Color := 0; Canvas.Pen.Width := 3; Canvas.LineTo((XPos + 150),(YPos + 150)); {------------Alte Winkel Zwischenspeichern-------------------------} SecWinkelAlt := SecWinkel; MinWinkelAlt := MinWinkel; StdWinkelAlt := StdWinkel; end; end. Dank Gruß MrFish |
Re: Analoguhr
Es wäre nicht schlecht, wenn du dein Projekt in den Anhang einfügen könntest. Dann muss man nicht selbst ein neues Projekt erstellen und kompilieren.
|
Re: Analoguhr
Liste der Anhänge anzeigen (Anzahl: 1)
Ist gemacht.
Hätte ich auch selbst drauf kommen können. :wall: |
Re: Analoguhr
Hi!
Es fehlen immer noch Sachen, z.B. dcu etc. Mach am besten das ganze Verzeichnis als zip und dann fehlt auch nix. In der Dpr steht übrigens ne absolutepfadangabe zu unit. Ciao fkerber |
Re: Analoguhr
Liste der Anhänge anzeigen (Anzahl: 1)
Nächster Versuch.
|
Re: Analoguhr
In dem Archiv fehlt wie gesagt noch die Pas-datei, die bei dir hier liegt:
C:\Programme\Borland\Delphi7\Projects\Uhr.pas Pack die noch da rein und ändere in der dpr-datei den pfad entweder auf \uhr.pas oder uhr.pas (bin mir nicht sicher sorry) ciao fkerber |
Re: Analoguhr
Also, die Idee ist nicht schlecht, aber ein bisschen konstruktive Kritik brauchts noch:
1. Der Kreis um die Uhr fehlt (zumindest bei mir), ebenso wie die Striche, die die Minuten bzw. Stundenpositionen zeigen 2. Wenn man schon die Größe des Fensters verändern kann, dann musst du darauf achten, dass es nicht zu klein werden kann. Dies kannst du mit den Constraints des Forms einstellen (MinHeight und MinWidth müssen gesetzt werden). Alternativ kanns du deinem Form eine fixe Größe zuweisen, und BorderStyle auf bsSingle setzen, somit kann die Größe nicht mehr geändert werden. 3. Du hast unten ein Edit mit der Zeit drin. Verwende dafür ein Label oder einen StaticText (register Zusätzlich). Edits sind für Eingaben, und nicht unbedingt für Ausgaben gemacht worden. Falls du wirklich ein Edit verwenden willst, so setze Enabled auf False, so dass der User nichts mehr eingeben kann. So, das musste raus, ansonsten find ich die Idee gut, und auch die Zeitanzeige scheint zu passen :thumb: |
DP-Maintenance
Dieses Thema wurde von "Daniel" von "Sonstige Fragen zu Delphi" nach "Open-Source" verschoben.
|
Re: Analoguhr
Liste der Anhänge anzeigen (Anzahl: 1)
bis ich das verstanden habe was alles zu einem Delphi Projekt gehört wird wohl noch eine Zeit vergehen.
|
Re: Analoguhr
Hallo MrFish,
Du solltest Dir angewöhnen aus den Variablen Objektfelder zu machen. So wie Du die Variablen jetzt deklariert hats handelt es sich um Globale-Variablen. In der OOP gehören Globale-Variablen zu den 42 Totsünden.
Code:
Wenn Du die Variablen als Objektfelder deklarierst würde Deine Formularklasse wie folgt aussehen:
SecWinkel : integer;
MinWinkel : Integer; StdWinkel : Integer; SecWinkelAlt : integer; MinWinkelAlt : integer; StdWinkelAlt : integer; Zeit : String; XPos : integer; YPos : Integer; Std : Integer; Min : Integer; Sec : Integer;
Delphi-Quellcode:
Jetzt musst Du noch im Source vor die Variablen das F schreiben. Das F gehört zu einer Nameskonvention. Alle Objektfelder sollten mit einem großen F beginnen. So wie alle Klassen mit einem großen T beginnen.
TAnaloguhr = class(TForm)
Edit1: TEdit; Uhr: TTimer; procedure UhrTimer(Sender: TObject); private { Private-Deklarationen } FMinWinkel : Integer; FStdWinkel : Integer; FSecWinkelAlt : integer; FMinWinkelAlt : integer; FStdWinkelAlt : integer; FZeit : String; FXPos : integer; FYPos : Integer; FStd : Integer; FMin : Integer; FSec : Integer; public { Public-Deklarationen } end; |
Re: Analoguhr
Zitat:
Es fehlt die "Analoguhr.dfm". Florian K. :thuimb: |
Re: Analoguhr
[Großes OT für MrFish]
Folgende Dateien gehören zu einem Projekt: Entwicklungsdateien: 1. <Projektname>.dpr: Die Projektdatei, welche dir das Mainform erzeugt und anzeigt. 2. <Projektname>.res: Die Datei, welche das Symbol der Anwendung beinhaltet 3. <Unitname>.pas: Die Quellcodedatei einer Unit 4. <Unitname>.dfm: Gibt es nur wenn die dazugehörige pas-Datei ein Form beinhaltet, diese Datei enthält die Definitionen des Forms 5. <Projektname>.exe und <Unitname.dcu> entstehen nur durch das Kompilieren; diese musst du nicht weitergeben (außer die exe vielleicht :wink:) [/OT] Ich hoffe das hilft dir |
Re: Analoguhr
pack doch einfach den gesamten Projekordner in ne zip-file !?
|
Re: Analoguhr
Hi!
@MrKnogge: Das wird wohl in dem Fall nicht reichen, weil die pas-Datei wie oben beschrieben, gaanz woanders liegt. Ciao fkerber |
Re: Analoguhr
Zunächt mal danke für eure Antworten.
@Jens Schumann Das mit dem Geltungsbereich ist klar, aber den Begriff Objektfeld höre ich zum ersten mal. Wo liegt der Unterschied zu normalen Variablen? @alcaeus Kritik wollte ich haben. :thuimb: Danke @all Ihr habt alle mitbekommen das ich Probleme habe die Bestandteile eines Projektes zu finde. :oops: Wie bekomme ich Delphi dazu alles in einem Ordner abzulegen? |
Re: Analoguhr
HI!
Projekt speichern unter speichern unter jeweils in den selben, vorher neu erstellten Ordner, dann iss alles drin, was rein muss. Ciao fkerber |
Re: Analoguhr
Liste der Anhänge anzeigen (Anzahl: 1)
Am besten wenn du ein neues project anfängst gleich mal: datei --> alles speichern...
und dann in einen zuvor! angelegten ordner. ps.: hab deinen code mal genommen und alles zusammengepackt (siehe anhang)...hoffe du bist nicht böse :duck: |
Re: Analoguhr
@ XeRo HAHA Jetzt funktioniert die Uhr. :-D
Vielleicht sollte man noch einen Kreis um die ganze uhr machen :roll: |
Re: Analoguhr
Zitat:
p.s.: mir ist gerade aufgefallen, dass ich bei der Timer procedure 2 mal begin geschrieben hab :oops: |
Re: Analoguhr
Zitat:
|
Re: Analoguhr
Also ich hab sie ir mal angesehen, man könnt zwar die ein oder andere kleinigkeit verbessern (glätten), aberfür den Anfang find ichs klasse :thuimb:
|
Re: Analoguhr
@XeRo
Ich bin dir nicht böse, sondern ich danke dir. @MrKnogge Das tut gut! Ich werde die Tips von euch umsetzen und das ganz noch mal schicken. Danke noch mal an alle. Bei der Hilfe macht das lernen Spaß. Gruß MrFish |
Re: Analoguhr
Liste der Anhänge anzeigen (Anzahl: 1)
Ich finde das irgendwie nicht so schön deinen Spaghetti-Code da. Du hast da ja im Prinzip immer wiederkehrenden Code zum Zeichnen der Zeiger nur mit anderen Winkeln und Längen. Schreib eine Prozedur dafür, der du die entsprechenden Werte als Parameter übergibst. So hast du keinen reduntanten Code. Siehe dazu meine Prozeduren ClearHands und PaintHands. Die hätte man auch noch zusammenfassen können, in dem man eine boolsche Variable mitgibt, die bestimmt, ob gezeichnet oder gelöscht werden soll.
Und durch das Zeichen auf das Bitmap im Speicher und das Kopieren des Bitmaps in OnPaint der Paintbox auf den Canvas der Paintbox, sind die Zeiger auch sofort wieder da, wenn das Fenster überdeckt wird und nicht erst nach einer Sekunde wieder, wenn bei dir der Timer ausgelöst wird. Ich würde es so lösen:
Delphi-Quellcode:
Damit wird auch die Uhr immer in der Mitte gezeichnet und die Zeiger passen immer drauf. Im Anhang noch mal das ganze Projekt.
type
TForm1 = class(TForm) Timer1: TTimer; PaintBox1: TPaintBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure PaintBox1Paint(Sender: TObject); procedure FormResize(Sender: TObject); private { Private declarations } OldHrs, OldMins, OldSecs: Integer; BackBitmap: TBitmap; // Bitmap im Speicher zum Zeichnen procedure ClearHands(Start: TPoint; Angle, Len: Integer); procedure PaintHands(start: TPoint; Angle, Len: Integer); public { Public declarations } end; const RADIUS = 100; var Form1 : TForm1; implementation {$R *.dfm} uses Math; {------------------------------------------------------------------------------} { Zeiger löschen } {------------------------------------------------------------------------------} procedure TForm1.ClearHands(Start: TPoint; Angle, Len: Integer); var EndPos : TPoint; begin // Anfangspunkt in die Mitte des Bitmaps setzten BackBitmap.Canvas.Pen.Color := clWhite; // Zeiger neu zeichnen EndPos.X := Trunc(sin(DegToRad(Angle)) * (RADIUS+Len)); EndPos.Y := Trunc(cos(DegToRad(Angle)) * -(RADIUS+Len)); BackBitmap.Canvas.MoveTo(Start.X, Start.Y); BackBitmap.Canvas.LineTo(Start.X+EndPos.X, Start.Y+EndPos.Y); end; {------------------------------------------------------------------------------} { Zeiger zeichnen } {------------------------------------------------------------------------------} procedure TForm1.PaintHands(Start: TPoint; Angle, Len: Integer); var EndPos : TPoint; begin // Anfangspunkt in die Mitte des Bitmaps setzten BackBitmap.Canvas.Pen.Color := clBlack; // Zeiger neu zeichnen EndPos.X := Trunc(sin(DegToRad(Angle)) * (RADIUS+Len)); EndPos.Y := Trunc(cos(DegToRad(Angle)) * -(RADIUS+Len)); BackBitmap.Canvas.MoveTo(Start.X, Start.Y); BackBitmap.Canvas.LineTo(Start.X+EndPos.X, Start.Y+EndPos.Y); end; {------------------------------------------------------------------------------} { Winkel der Zeiger berechnen } {------------------------------------------------------------------------------} procedure CalcAngels(var hrs, mins, secs, msec: Word); begin DecodeTime(Time, hrs, mins, secs, msec); secs := secs * 6; mins := mins * 6; hrs := hrs * 30; end; {------------------------------------------------------------------------------} { Form erzeugen } {------------------------------------------------------------------------------} procedure TForm1.FormCreate(Sender: TObject); begin DoubleBuffered := True; // Bitmap im Speicher erzeugen BackBitmap := TBitmap.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin // Bitmap im Speicher wieder freigeben FreeAndNil(BackBitmap); end; procedure TForm1.Timer1Timer(Sender: TObject); var hrs, mins, secs, msec : Word; Start : TPoint; begin // Zeit zur Kontrolle mitlaufen lassen Caption := TimeToStr(Time); // Größe des Bitmaps an die Größe der Paintbox (Align := alClient anpassen BackBitmap.Width := Paintbox1.Width; BackBitmap.Height := Paintbox1.Height; // Startpunkt berechnen (soll immer in der Mitte der Paintbox sein Start.X := Paintbox1.Width div 2; Start.Y := Paintbox1.Height div 2; // Winkel berechnen CalcAngels(hrs, mins, secs, msec); // Zeiger löschen ClearHands(Start, OldSecs, Paintbox1.Height div 2 div 2 - 40); // Zeiger zeichnen PaintHands(Start, secs, Paintbox1.Height div 2 div 2 - 40); // alten Winkel merken OldSecs := secs; ClearHands(Start, OldMins, Paintbox1.Height div 2 div 3 - 50); PaintHands(Start, mins, Paintbox1.Height div 2 div 3 - 50); OldMins := mins; ClearHands(Start, OldHrs, Paintbox1.Height div 2 div 6 - 60); PaintHands(Start, hrs, Paintbox1.Height div 2 div 6 - 60); OldHrs := hrs; // Neuzeichnen der Paintbox auslösen Paintbox1.Repaint; end; {------------------------------------------------------------------------------} { OnPaint der Paintbox } { Bitmap im Speicher auf die Paintbox kopieren } {------------------------------------------------------------------------------} procedure TForm1.PaintBox1Paint(Sender: TObject); begin BitBlt(Paintbox1.Canvas.Handle, 0, 0, Paintbox1.Width, Paintbox1.Height, BackBitmap.Canvas.Handle, 0, 0, SRCCOPY); end; {------------------------------------------------------------------------------} { Größe des Bitmap im Speicher auf null setzen } {------------------------------------------------------------------------------} procedure TForm1.FormResize(Sender: TObject); begin BackBitmap.Width := 0; BackBitmap.Height := 0; end; |
Re: Analoguhr
@Luckie
Das ist ja wahnsinn was du dir für eine Mühe gemacht hast. Ich habe deinen Source durchgearbeitet und viel dabei gelernt. Danke :love: |
Re: Analoguhr
War nicht viel Mühe. War im Prinzip in einer halben Stunde fertig, danach noch etwas Kosmetik und ein zwei Bugs ausmerzen, das war schon alles.
|
Re: Analoguhr
@Luckie: Sauberer Code, aber der Kreis um die Uhr fehlt immer noch ;) :lol
|
Re: Analoguhr
Zitat:
|
Re: Analoguhr
Zitat:
|
Re: Analoguhr
Das Problem war, ich war zu faul die Koordinaten auszurechnen für die Minutenstriche bzw. dafür eine Routine zuschreiben, die selbiges in einer Schleife erledigt. :?
|
Re: Analoguhr
ganz toll wär jetzt, das ganze in ne komponente zu schmeissen
aber für nen anfänger...(ich kanns auch nicht :-D ) |
Re: Analoguhr
haha ;) du genie du :D
aber wenn ich mir mein erstes programm anschaue dann denke ich mir was hab ich am anfang falsch gemacht :( :thuimb: für nen Anfänger |
Re: Analoguhr
:warn:
ich hab nicht gesagt, das das prog fürn anfänger leicht ist (ich wüsste nicht, ob ichs könnte...) |
Re: Analoguhr
hat ja auch niemand behauptet das du das gesagt hast :mrgreen: ;)
|
Re: Analoguhr
stimmt auch wieder :-D
wenn ich mir anschaue, was ich mir am anfang da zusammengesch**** hab.... :duck: ich versteh die quelltexte heute selber nicht mehr, statt se mir durzulesen, schreib ich se neu |
Re: Analoguhr
Ich habe den schönen Code von Luckie verunstaltet. Jetzt hat die Uhr ein Ziffernblatt.
@Luckie Ich habe da noch zwei Fragen: 1 Du nutzt die Procedure CalcAngel. Ich dachte bisher das jede Procedure deklariert werden muss. Ich finde aber keine Deklaration dafür. Was stimmt hier nicht. :wiejetzt: 2 Die unterstrichene Codeteile verstehe ich nicht. Ich habe zwar erkannt des das die Zeigerlänge ist aber mehr auch nicht. Kannst du mir daq eine genauere Erklärun geben. :wall:
Delphi-Quellcode:
[edit=Luckie]Delphi-Tag geschlossen. Mfg, Luckie[/edit]// Zeiger löschen ClearHands(Start, OldSecs, [u]Paintbox1.Height div 2 div 2 - 40[/u], 1); // Zeiger zeichnen PaintHands(Start, secs, [u]Paintbox1.Height div 2 div 2 - 40[/u], 1); // alten Winkel merken OldSecs := secs; ClearHands(Start, OldMins, [u]Paintbox1.Height div 2 div 3 - 45[/u], 2); PaintHands(Start, mins, [u]Paintbox1.Height div 2 div 3 - 45[/u], 2); OldMins := mins; ClearHands(Start, OldHrs, [u]Paintbox1.Height div 2 div 6 - 55[/u], 4); PaintHands(Start, hrs, [u]Paintbox1.Height div 2 div 6 - 55[/u], 4); OldHrs := hrs; |
Re: Analoguhr
Wenn ich die Form vergrößere werden die zeiger größer aber nicht der kreis um die zeiger... :wink:
|
Re: Analoguhr
sieht doch schon richtig gut aus :thuimb:
was ncoh fehlt, sind zahlen um den kreis..... :-D |
Re: Analoguhr
hallo mrfish!
werd nicht gleich nervös! luckie wird schon noch vorbeischauen! :mrgreen: in der zwischenzeit beantworte ich mal deine frage zur procedure 'CalcAngels' wie du siehst, kann man auch 'nichtdefinierte' proceduren verwenden, und zwar dann, wenn sie nur in jener unit verwendet werden, in der sie erstellt sind. es spricht ja nichts dagegen, oder? nachdem CalcAngels nur eine berechnung durchführt und nicht in direktem zusammenhang mit Form1 steht, ist es auch nicht notwendig, sie in die objektdefinition aufzunehmen. CalcAngels ist eine procedure, die du zb in einer eigenen unit auslagern und später in anderen programmen einbinden könntest. dann ist sie allerdings im interface-abschnitt der unit anzuführen, sonst wird sie von den anderen programmen nicht gefunden (sie wird ja nun ausserhalb der unit verwendet, in der sie zu finden ist. klar?) ich hoffe, dass ich mich nicht zu kompliziert ausgedrückt habe *gg* mfg, stefan |
Re: Analoguhr
Die Prozedur muss nur zum Zeitpunkt der Benutzung bekannt sein. Deklariere ich A vor B kann ich A in B benutzen aber nicht B in A.
|
Re: Analoguhr
jup! so kann man es auch sagen ;)
mfg, stefan |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz