Eine Linie Zeichnen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Eine Linie Zeichnen

Beitrag von DL3AD »

Hallo,

ich möchte eine Linie zeichnen in auf einem Panel von Punkt1 X1,Y1 nach Punkt Y1,Y2.
Wie und mit welchem Control kann ich das machen ?

Gruß Frank

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Eine Linie Zeichnen

Beitrag von theo »

Dafür brauchst du keine Extra Komponente.
Ein Panel hat ein OnPaint Ereignis, da drin malst du auf den Canvas.

Code: Alles auswählen

P1.Canvas.Pen.Color:= clRed;
P1.Canvas.MoveTo(5,5);
P1.Canvas.LineTo(25,25);

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Eine Linie Zeichnen

Beitrag von DL3AD »

... ahha Danke. 8)

tightTannic
Beiträge: 20
Registriert: Di 31. Jan 2017, 19:46
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Berlin

Re: Eine Linie Zeichnen

Beitrag von tightTannic »

Wenn du auf dem Panel viel zeichnest (Farben änderst usw.), könnte für dich With ** do ** interessant sein, da es eine verkürzte Schreibweise ermöglicht:

Code: Alles auswählen

With P1.Canvas do begin
// bei jeder Anweisung die sich nun auf P1.Canvas bezieht, kannst du nun das "P1.Canvas." weglassen
    Pen.Color:= clRed; // anstelle von P1.Canvas.Pen.Color:= clRed;
    MoveTo(5,5);
    LineTo(25,25);   
end:

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eine Linie Zeichnen

Beitrag von Mathias »

Code: Alles auswählen

   MoveTo(5,5);
   LineTo(25,25);   

Dies kann man auch durch ein einfaches

Code: Alles auswählen

   Line(5, 5, 25, 25);   

ersetzen. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Eine Linie Zeichnen

Beitrag von theo »

tightTannic hat geschrieben:könnte für dich With ** do ** interessant sein, da es eine verkürzte Schreibweise ermöglicht:

...und somit zur Unleserlichkeit, erschwertem Debugging und komplett überflüssigen Fehlern führt...

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eine Linie Zeichnen

Beitrag von Mathias »

theo hat geschrieben:
tightTannic hat geschrieben:könnte für dich With ** do ** interessant sein, da es eine verkürzte Schreibweise ermöglicht:

...und somit zur Unleserlichkeit, erschwertem Debugging und komplett überflüssigen Fehlern führt...

Darüber könnte man streiten, in solchen Fällen finde ich es mit with auch übersichtlicher.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Eine Linie Zeichnen

Beitrag von braunbär »

With, so wie derzeit in Pascal implementiert, ist generell ein unsicheres Konstrukt, aber gerade in solchen Fällen auf jeden Fall zu vermeiden.

Bist du sicher, dass du die Namen aller Members von TCanvas inklusive der in Vorfahrklassen vorkommenden Properties und Datenfelder immer präsent hast?
Wenn du zufällig irgend eine (lokale oder globale) Variable oder vielleicht eine Property der Form so nennst wie eine Property des TCanvas (oder eines Vorfahren) und die im Inneren des with-Blocks verwendest, dann bekommst du keinerlei Warnung, aber das Programm arbeitet mit einer ganz anderen Variablen als mit der, von der du das glaubst, mit möglicherweise völlig rätselhaften Folgefehlern, die dann u.U. erst an ganz anderen Stellen des Programms sichtbar werden.
Ganz abgesehen davon, dass du nie wissen kannst, ob in einer späteren Version der LCL vielleicht eine TCanvas-Property mit so einem Namen eingeführt wird. Viel Spaß dann bei der Fehlersuche, wenn du die Lazarus/FPC Version aktualisierst und dein Programm plötzlich Mist macht.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Eine Linie Zeichnen

Beitrag von siro »

Ich fand die "With" Anweisung bisher SEHR übersichtlich und würde mich freuen wenn es so etwas auch in "C" geben würde. :cry:
Das erhöht ungemein die Lesbarkeit des Codes. Ich hatte da bisher noch keine Probleme mit, muss aber zugeben, dass ich
auch so einige Male auf einem falschen Canvas gezeichnet habe, da ich garkeinen Verweis angegeben habe. :P
Wenn die .paint Methode den canvas übergeben würde, wären viele Probleme beseitigt, wobei man den ja über Sender. ermitteln kann.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: Eine Linie Zeichnen

Beitrag von compmgmt »

braunbär hat geschrieben:Wenn du zufällig irgend eine (lokale oder globale) Variable oder vielleicht eine Property der Form so nennst wie eine Property des TCanvas (oder eines Vorfahren) und die im Inneren des with-Blocks verwendest, dann bekommst du keinerlei Warnung, aber das Programm arbeitet mit einer ganz anderen Variablen als mit der, von der du das glaubst, mit möglicherweise völlig rätselhaften Folgefehlern, die dann u.U. erst an ganz anderen Stellen des Programms sichtbar werden.
Deswegen passt man auf wie man seine Variablen nennt ;)

braunbär hat geschrieben:Ganz abgesehen davon, dass du nie wissen kannst, ob in einer späteren Version der LCL vielleicht eine TCanvas-Property mit so einem Namen eingeführt wird. Viel Spaß dann bei der Fehlersuche, wenn du die Lazarus/FPC Version aktualisierst und dein Programm plötzlich Mist macht.
Kannst du dir bei nichts sicher sein. Ist bei Klassen, Units, Methoden, Funktionen, ... genau das gleiche

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Eine Linie Zeichnen

Beitrag von braunbär »

compmgmt hat geschrieben: Ist bei Klassen, Units, Methoden, Funktionen, ... genau das gleiche

Nein. Das Problem hast du nur in Verbindung mit dem with Statement. Sonst kann es dir prinzipiell egal sein, ob irgendwo ein neuer, zusätzlicher Variablenname eingeführt wird, der kann bestehenden Code nicht brechen.

Außer in Verbindung mit globalen Variablen, von deren Verwendung ja ebenfalls abgeraten wird. Ich habe in jedem Projekt eine unit GlobalData, in der ich alle im Projekt verwendeten globalen Daten in einem record gd zusammenfasse, und der Zugriff auf eine globale Variable im Programm erfolgt deshalb immer über gd.Variablenname.

siro hat geschrieben:Ich fand die "With" Anweisung bisher SEHR übersichtlich

"Sehr übersichtlich" hat nichts mit unsicher zu tun. Das Problem besteht darin, dass Änderungen an einer ganz anderen Stelle des Programms bestehenden Code brechen können. In einem kleinen 100 Zeilen Programm ist das wohl kein Problem, aber bei größeren Projekten ist es ein absolutes Nogo. Es ist uns einmal passiert (seinerzeit noch mit Turbo Pascal), und die Folgen waren verheerend - Falsche Daten in Datenbanken draußen bei den Kunden, die Ursache haben wir 2 Wochen gesucht, bis wir endlich draufgekommen sind. Seither war das with Statement absolut tabu.
Zuletzt geändert von braunbär am Mo 14. Aug 2017, 10:34, insgesamt 1-mal geändert.

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: Eine Linie Zeichnen

Beitrag von compmgmt »

braunbär hat geschrieben:
compmgmt hat geschrieben: Ist bei Klassen, Units, Methoden, Funktionen, ... genau das gleiche

Nein. Das Problem hast du nur in Verbindung mit dem with Statement. Sonst kann es dir prinzipiell egal sein, ob irgendwo ein neuer, zusätzlicher Variablenname eingeführt wird, der kann bestehenden Code nicht brechen.

Außer in Verbindung mit globalen Variablen, von deren Verwendung ja ebenfalls abgeraten wird. Ich habe in jedem Projekt eine unit GlobalData, in der ich alle im Projekt verwendeten globalen Daten in einem record gd zusammenfasse, und der Zugriff auf eine globale Variable im Programm erfolgt deshalb immer über gd.Variablenname.
Ich meinte damit, dass es auch durchaus sein kann, dass es in Lazarus irgendwann mal eine unit, Klasse oder sonst irgendwas geben könnte, die so heißt wie eine von dir. Das ist kein größeres Problem, bedarf aber einer eventuellen (kleinen) Umschreibung deines Programms.

Und ich finde die Nutzung von "with" durchaus praktisch. Bei meiner Schaltplansoftware habe ich bspw eine Stelle, bei dem eine StringListe mit 120 hard gecodeten Strings befüllt wird (Weil die Sprache Deutsch als einzige hard gecoded ist, alle anderen Sprachen sind dynamisch). Da ist so etwas durchaus nützlich.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Eine Linie Zeichnen

Beitrag von braunbär »

compmgmt hat geschrieben:Und ich finde die Nutzung von "with" durchaus praktisch.

Siehe Post unmittelbar darüber - das Editieren hat sich mit deinem Post überschnitten.
Der potentielle Schaden durch ein with kann den Nutzen, der aus dem Weglassen eines Bezeichners resultiert, um ein vielfaches übersteigen. Statt zwei Wochen Fehlersuche und den Ärger mit den Kunden hätte ich liebend gerne auf alle With-Statements, die wir je in unseren Programmen verwendet haben, verzichtet. Aber es gibt wahrscheinlich Erfahrungen, die jeder einmal selbst machen muss...

compmgmt hat geschrieben:Ich meinte damit, dass es auch durchaus sein kann, dass es in Lazarus irgendwann mal eine unit, Klasse oder sonst irgendwas geben könnte, die so heißt wie eine von dir. Das ist kein größeres Problem, bedarf aber einer eventuellen (kleinen) Umschreibung deines Programms.

Außer in Verbindung mit with ist es gar kein Problem. Wenn du etwas lokal definierst, hat das Priorität gegenüber einer globaleren Definition. Aber in Verbindung mit with kann es zu einem ernsten Problem werden, weil der Compiler dich nicht darauf hinweist (und das auch gar nicht kann), dass sich die Semantik deines Codes gegenüber früher geändert hat.

Es wäre sehr leicht, aus dem unsicheren with-Konstrukt durch geringfügige Syntax-Änderung ein sicheres Konstrukt zu machen. Schade ist, dass das nicht gemacht wird.

Bei meiner Schaltplansoftware habe ich bspw eine Stelle, bei dem eine StringListe mit 120 hard gecodeten Strings befüllt wird

So etwas würde ich nicht mit einer Stringlist, sondern mit einem initialisierten String-array machen. Wozu zur Laufzeit initialisieren?

Antworten